What are the advantages of defining a private attribute instead of a public attribute? Why should I have the extra work of creating methods to access and modify privates attributes if I can just make them public?
If you use getters/setters you can perform logic upon changes or access. You could validate input, instead of assuming it is always correct. You could track how many times the value is fetched.
Most of all, it's good design. It gives you, the developer of the class, more control over how it is used and a greater ability to prevent misuse, abuse, or just someone doing something wrong.
If you create access method, you separate implementation from interface.
because you should always strive to defend the implementation from the interface. if you make an attribute public, you are letting the client know how your implementation for that attribute is.
This binds you in keeping not only the interface, but also the implementation.
Also, you can perform other smart things like validation, access control, accounting, if you use a method. If you make an attribute public, you have much less control of what the client can do with that attribute
A private attribute provides you a level of protection from the users of your class, for that attribute. If you use a public attribute, you will need to add in more logic to test for invalid values up front, which can be more work, as well as more computationally expensive.
Public attributes also "clutter" the interface. The fewer public attributes you present, the "cleaner" and easier your object will be to work with. Having some attributes private gives you flexibility while providing an ease of use that would otherwise not be there.
In C# it is idiomatic. That means that public fields would be surprising, and make other people take a little longer to understand your code.
The reason it is idiomatic has to do with the other explanations people are giving, but the fact that it's idiomatic means that you should prefer a property over a public field unless there's a compelling reason to use a field.
In the short term there's none, other than making OOP purists unhappy.
(I'm assuming you mean exposing properties that would otherwise use getters/setters - obviously there's a big difference if you leave ALL your attributes public).
In the long-term there are a few really good reasons for doing it.
Firstly it allows you to validate input at its source instead of later having to back-track the origin with a combination of hardware breakpoints and black-magic.
E.g.
void Foo::setWeight(float weight)
{
ASSERTMSG(weight >= 0.0f && weight <= 1.0f, "Weights must fall in [0..1]");
mWeight = weight;
}
It also allows you to later change the behavior of your object without needing to refactor client code.
E.g.
void Foo::setSomething(float thing)
{
mThing = thing;
// 2009/4/2: turns out we need to recalc a few things when this changes..
...
}
Mainly because of OO concept of encapsulation. Using private you encapsulate the access to your object variable keeping the control of the object status. Not allowing external objects to change the status of your object that you are not aware.
A simple example would be a Pocket object.
class Pocket {
public int numberOfCoins = 10;
private boolean haveMoney = true;
public void giveOneCoin(){
if(stillHaveMoney()){
numberOfCoins--;
if(numberOfCoins=<0){
haveMoney=false;
}
}
}
public boolean stillHaveMoney(){
return haveMoney;
}
}
And now imagine another class as below:
class PickPockets {
public void getSomeMoney(Pocket pocket){
pocket.numberOfCoins=0;
}
}
Surely it's a simple example. however this shows how it's important to have control of the access to your class fields/attributes. Imagine a more complex object with a much more complicated state control. Encapsulation makes the abstraction and consistency of the object better.
Typically you would use Private declarations for fields you want to isolate within your program's logic, ONLY if you deem necessary.
Public declarations give you more control of your own program's flow; you can change public fields whenever you wish. You are the man in the house.
So, why most people spontaneously respond with a BIG YES to Private declarations?
Because:
- They were taught to do it "just like that" in college. (most prudent reason)
- They ultimately, foolishly and immediately assume that you are either building a code library, building a software component for others to consume OR working on some cryptography implementation. ONLY in these cases would you not be sure what would happen to your fields.
Bottom-line is amazingly "commercial"!! If you are "selling" it, then go private, otherwise do what you like.
You are better off in the long term if all attributes are private. That includes not using getters. If you are accessing attributes of objects then you are breaking encapsulation, and aren't really doing OOP at all. At that point, most of the reason for building a class has been wasted. Why build a castle to protect from intruders, then leave all the doors open? Or (with getters) always welcome the intruders in on request.
The methodologies of "Law of Demeter" and "Tell don't ask" has been shown to reduce bug rate in production code. Using public attributes won't make object oriented purists unhappy, it'll just ward them off using your code.
Tell your objects what to do with their attributes, don't ask them for the values, manipulate them and write them back. That would be like taking a dog for a walk and then picking up its legs one by one to get it to move.
By the way, conversely, behaviour should all be public. Any method that seems like it should be private is actually an unextracted method of another class. Extract that class and method and watch your design simplify before your very eyes.