views:

210

answers:

9

Hello everybody!

I've always wondered on the topic of public, protected and private properties. My memory can easily recall times when I had to hack somebody's code, and having the hacked-upon class variables declared as private was always upsetting.

Also, there were (more) times I've written a class myself, and had never recognized any potential gain of privatizing the property. I should note here that using public vars is not in my habit: I adhere to the principles of OOP by utilizing getters and setters.

So, what's the whole point in these restrictions?

+2  A: 

The keyword private shouldn't be used to privatize a property that you want to expose, but to protect the internal code of your class. I found them very helpful because they help you to define the portions of your code that must be hidden from those that can be accessible to everyone.

Maurizio Reginelli
Why should you want to hide your code from anyone? :)
Denis Gorbachev
A: 

One example that comes to my mind is when you need to do some sort of adjustment or checking before setting/getting the value of a private member. Therefore you'd create a public setter/getter with some logic (check if something is null or any other calculations) instead of accessing the private variable directly and always having to handle that logic in your code. It helps with code contracts and what is expected.

Another example is helper functions. You might break down some of your bigger logic into smaller functions, but that doesn't mean you want to everyone to see and use these helper functions, you only want them to access your main API functions.

In other words, you want to hide some of the internals in your code from the interface.

See some videos on APIs, such as this Google talk.

Bryan Denny
What if I make a mistake in these public setters/getters?What if a user of my class would extend it in a way that actually *needs* those helper functions?
Denis Gorbachev
+4  A: 

The whole point is to use private and protected to prevent exposing internal details of your class, so that other classes only have access to the public "interfaces" provided by your class. This can be worthwhile if done properly.

I agree that private can be a real pain, especially if you are extending classes from a library. Awhile back I had to extend various classes from the Piccolo.NET framework and it was refreshing that they had declared everything I needed as protected instead of private, so I was able to extend everything I needed without having to copy their code and/or modify the library. An important take-away lesson from that is if you are writing code for a library or other "re-usable" component, that you really should think twice before declaring anything private.

Justin Ethier
If a class user could extend it and, presumably, write some direct setters/getters, then all this `protected` stuff becomes just like `public`. Why not declare everything `public` from the beginning?
Denis Gorbachev
Because then there would be no encapsulation. The point of protected is that those elements can only be accessed by this class or its decedents - these objects need to know the internal details, but any external code that uses them does not.
Justin Ethier
But any user could extend my class and break the encapsulation in any way he wants. There is *no* effective encapsulation with `protected`.
Denis Gorbachev
A: 

Having recently had the extreme luxury of being able to design and implement an object system from scratch, I took the policy of forcing all variables to be (equivalent to) protected. My goal was to encourage users to always treat the variables as part of the implementation and not the specification. OTOH, I also left in hooks to allow code to break this restriction as there remain reasons to not follow it (e.g., the object serialization engine cannot follow the rules).

Note that my classes did not need to enforce security; the language had other mechanisms for that.

Donal Fellows
A: 

In my opinion the most important reason for use private members is hiding implementation, so that it can changed in the future without changing descendants.

mschayna
A: 

Some languages - Smalltalk, for instance - don't have visibility modifiers at all.

In Smalltalk's case, all instance variables are always private and all methods are always public. A developer indicates that a method's "private" - something that might change, or a helper method that doesn't make much sense on its own - by putting the method in the "private" protocol.

Users of a class can then see that they should think twice about sending a message marked private to that class, but still have the freedom to make use of the method.

(Note: "properties" in Smalltalk are simply getter and setter methods.)

Frank Shearar
I appreciate this warning-style. Actually, that's what I advocate for.
Denis Gorbachev
A: 

I personally rarely make use of protected members. I usually favor composition, the decorator pattern or the strategy pattern. There are very few cases in which I trust a subclass(ing programmer) to handle protected variables correctly. Sometimes I have protected methods to explicitly offer an interface specifically for subclasses, but these cases are actually rare.

Most of the time I have an absract base class with only public pure virtuals (talking C++ now), and implementing classes implement these. Sometimes they add some special initialization methods or other specific features, but the rest is private.

Space_C0wb0y
+7  A: 

The use of private and public is called Encapsulation. It is the simple insight that a software package (class or module) needs an inside and an outside.

The outside (public) is your contract with the rest of the world. You should try to keep it simple, coherent, obvious, foolproof and, very important, stable.

If you are interested in good software design the rule simply is: make all data private, and make methods only public when they need to be.

The principle for hiding the data is that the sum of all fields in a class define the objects state. For a well written class, each object should be responsible for keeping a valid state. If part of the state is public, the class can never give such guarantees.

A small example, suppose we have:

class MyDate
{ 
    public int y, m, d;
    public void AdvanceDays(int n) { ... } // complicated month/year overflow
    // other utility methods
};

You cannot prevent a user of the class to ignore AdvanceDays() and simply do:

date.d = date.d + 1; // next day

But if you make y, m, d private and test all your MyDate methods, you can guarantee that there will only be valid dates in the system.

Henk Holterman
Yeah, right. But what if I make a horrible mistake in `AdvanceDays`? The users of my class won't be able to fix it if all the data is private.
Denis Gorbachev
You're obviously working in another direction here. Your users should just kick you (:
Henk Holterman
If I had it all public, they wouldn't need to)
Denis Gorbachev
Better make that a full smiley, you are advocating to make a bad situation worse.
Henk Holterman
A: 

First of all 'properties' could refer to different things in different languages. For example, in Java you would be meaning instance variables, whilst C# has a distinction between the two.

I'm going to assume you mean instance variables since you mention getters/setters.

The reason as others have mentioned is Encapsulation. And what does Encapsulation buy us?

Flexibility

When things have to change (and they usually do), we are much less likely to break the build by properly encapsulating properties.

For example we may decide to make a change like:

int getFoo()
{
  return foo;
}

int getFoo()
{
  return bar + baz;
}

If we had not encapsulated 'foo' to begin with, then we'd have much more code to change. (than this one line)

Another reason to encapsulate a property, is to provide a way of bullet-proofing our code:

void setFoo(int val)
{
  if(foo < 0)
    throw MyException(); // or silently ignore

  foo = val;
}

This is also handy as we can set a breakpoint in the mutator, so that we can break whenever something tries to modify our data.

If our property was public, then we could not do any of this!

Steven
Yes, we could. Every programmer has learned to use getters/setters when they are provided. Encapsulation is good, but privatizing is not, in my opinion. What do you think?
Denis Gorbachev
They may have a method wrapping them, but (if you can bypass that method) they are not encapsulated.I disagree that every programmer will go through getters/setters if they are provided (and there is an option of directly accessing the field.)The excuse I've heard for this is 'efficiency reasons'.This is nonsense, and the maintenance problem would greatly outway any processor cycles that you could save.
Steven