views:

98

answers:

4

Im trying to understand the benefits of making a class variable private, versus public. I understand getters / setters to access / modify the private / protected data, but is its sole purpose is to 'keep me from mangling my data'? Example : I dont get how saying

$person->age = x;//bad?

has different potential for havoc than

$person->set_x(x);//reccommended in OOP articles
A: 

Keep you from mangling it, keep others from mangling it, and express the idea that non-public members are not part of what others should see -thus achieving Encapsulation.

Oren A
"keep others from mangling it" - So, when its just me, and a small project, cool. Otherwise, getter() setter() the inner class workings? Is that the consensus?
jason
No, I specifically mentioned "you" first, and keep in mind that you will not be able to remember with which fields you should or should not "mangle" even if it is a small project, let alone if a few weeks or even days will pass. And last but not least - as a general rule- there is no difference in best practices between if you're writing a project alone or if you are a part of a team.
Oren A
@jason it's not a matter of the size of the team. It's a matter of clean, maintainable, stable code base.
Ondrej Tucny
+11  A: 

It's all about encapsulation.

Say you use $person->age = x. For now, it'll work fine, and let's say you have that line in 100 places. Later on it turns out that you want to restrict age to, say, numbers greater than 0. With direct access to the member variable, there's no way to easily enforce that restriction.

But let's say you'd originally written $person->set_age(x) in those 100 places. Now, you can change your setter from

private $_age;
public void age($new_age) {
    $this->_age = $new_age;
}

to

private $_age;
public void age($new_age) {
    if ($new_age > 0) {
        $this->_age = $new_age;
    }
}

You don't have to touch a single consumer of the set_age method; the changes "just work". That's the real beauty of OOP: you can hide a lot of implementation details behind a single method call.

The encapsulation can help elsewhere, too: say you wanted a subclass of Person that logged every age change. With the setter method, it's as easy as an override; with direct variable access, it would be a mess.

kevingessner
This is why I <3 SO. Upboat.
jason
Yes, the reason for getters and setters is mainly for the validation of the new value, you dont want an `integer` where a `resource` or `bool` is required do you.
RobertPitt
A: 

Well, I think the set/get method can help better gurantee the attributes, as if you directly change the value might cause some troubles, e.g. harmful to the code. I think the set/get provide a method for the user to call rather than directly operate on the attributs.

ladyfafa
+3  A: 

By providing accessors (setter / getter methods, or by using properties in languages that support them, like C#) the developer can define a more-stable contract between the class and its users. Instead of accessing a field directly, by actually reading or writing a memory location, the user is forced to call a method, that in turn can encapsulate any logic necessary.

In turn when modifying the class'es internal design, its contract needs to be changed less frequently. Hence maintainability and stability of the code is improved.

Note that performance is not a concern, because modern JIT compilers are able to optimize calls to trivial getters / setters in a way that the actual call is eliminated and the code is equivalent to direct access to the underlying memory location.

Edit:

Also, setter and getter may usually have different visibility (public / protected / private) providing the added benefit of more-granular control to read / write operations over a specified value.

Hence the best practice is to avoid public fields wherever possible and use setter / getter methods or properties instead.

Ondrej Tucny