How do I properly use Properties/getters/setters?

Started by
16 comments, last by Alpha_ProgDes 15 years, 10 months ago
The idea of getters and setters or Properties is not complicated. But this irks me to know end:

//C, C++, Java
int getIndex()
{
   return index;
}

int setIndex(int indexToSet)
{
   index = indexToSet;
}

//C#
int Index
{
   get
   {
       return index;
   }

   set
   {
       index = value;
   }
}

Why, oh, why would you do this? Why not just make the fields public and be done with it? Is doing it this way really good OOD/OOP? What is the benefit of doing it this way that I'm missing? [Edited by - Alpha_ProgDes on June 15, 2008 11:53:59 PM]

Beginner in Game Development?  Read here. And read here.

 

Advertisement
Properties can be read-only and/or do extra work when they are set.
They are also necessary if you want to use interfaces.

e.g. you could make a rectangle class that recalculates it's area when its width or height is set.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
I know what you mean, but one potential rationale comes to mind. If you ever choose to do some checking on the values or need to protect it for any other reason, then you won't have to break the interface if you just make it a property to begin with. It's safer in the long-term to just make it a property.
OOP:
-Inheritance
-Encapsulation*
-Abstraction
-Polymorphism

... Thats why.
Usually you shouldn't have set/get functions for all of your member variables anyway. If you do, its probably a sign that either your classes are too tightly coupled, or that you're just dealing with a simple "data holding structure" that can safely be public.

That said, people often use set/get functions just in case access requirements change later on. It's much easier to refactor that way...
In c#, i think i used to use set() mostly as the source site for firing an event on the delegate to indicate that the property state has changed to interested observers ie on_color_changed.

a practical advantage of the property was that you could invoke automatic serialisation behavour without having to explicitly state this attribute on the field.

The other use cases that follow from property encapsulation apart from information hiding are that you can make the property polymorphic - although i think you would want a strong use case to justify the additional design complication - it doesnt seem a natural or useful fit to something that is just a state representation.

I admit to having found property getters and setters to be a really verbose syntax in c# - and i never found a way to overide the autoformatting of the setter/getter which would break over multiple lines in the vs editor.
Quote:Original post by Hodgman
Usually you shouldn't have set/get functions for all of your member variables anyway. If you do, its probably a sign that either your classes are too tightly coupled, or that you're just dealing with a simple "data holding structure" that can safely be public.

That said, people often use set/get functions just in case access requirements change later on. It's much easier to refactor that way...
Wrong. Any member variable which needs to be accessed outside the class should require getter/setter methods.

For instance you might need to make your setter/getters synchronized for thread-safety. Or you might want to check the values passed into the setter are sensible - all public methods should check input values in an ideal world. Or you might want to update your GUI based on the values stored, or even update a database in the same way.

Personally, I can't stand getters and setters. It's often either bad OO-design or unnecessary code bloat. In many cases, you can get away by using immutable value types with public constants, for example:

public class Person{    public final String surname, forename, initials;    public Person(String surname, String forename, String initials)    {        this.surname = surname;        this.forename = forename;        this.initials = initials;    }    @Override    public boolean equals(Object o)    {        if (!(o instanceof Person)) return false;        Person p = (Person) o;        return surname.equals(p.surname)            && forename.equals(p.forename)            && initials.equals(p.initials);    }        @Override    public int hashCode()    {        return (surname.hashCode() * 37 +                forename.hashCode()) * 37 +                initials.hashCode();    }}
Another reason to use them in C# is that they are identified as such when performing reflection, and will show up in controls such as the PropertyGrid automatically.

At least C#3 makes life easier:
public int Index { get; set; }

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

Quote:Original post by d000hg
Quote:Original post by Hodgman
Usually you shouldn't have set/get functions for all of your member variables anyway. If you do, its probably a sign that either your classes are too tightly coupled, or that you're just dealing with a simple "data holding structure" that can safely be public.

That said, people often use set/get functions just in case access requirements change later on. It's much easier to refactor that way...
Wrong. Any member variable which needs to be accessed outside the class should require getter/setter methods.

For instance you might need to make your setter/getters synchronized for thread-safety. Or you might want to check the values passed into the setter are sensible - all public methods should check input values in an ideal world. Or you might want to update your GUI based on the values stored, or even update a database in the same way.

I think what Hodgman means is that being able to modify state through direct access to data members, be it using get/setters or public variables, is an indication of bad design and a lack of abstraction:
player.magic -= 1;player.fatigue *= 1.1;enemy.health -= 10;
vs.
character.atack(enemy);


On the OP: yes, if you're sure public variables will do the trick just fine, don't use property wrappers. In a (mathematical) vector class it would be silly and downright annoying to use getters and setters for the individual components. In less straightforward cases, using them may make refactoring code later on slightly easier, but a proper IDE and a well designed system shouldn't make those changes like that too difficult and time consuming anyway.

This topic is closed to new replies.

Advertisement