4

If I create a class in Java, I've always been taught that the convention is to make all fields of a class private. If I need to access or change them, I can create an accessor and mutator method. I do understand the importance of private variables, as they help reduce complexity and allow for encapsulation.

What I don't understand is that if I create a public accesor and mutator method, isn't the variable public at that point? Why is it still convention to use private variables in situations where anyone can access them?

I should also note that I understand the important of these methods, but I would like to know why we bother to make the variable private even though we are giving anyone access to it through those methods?

AdamMc331
  • 16,492
  • 10
  • 71
  • 133
  • 1
    Thread-safety, side effects of other functions in the class on the variable. Furthermore, OOP is about abstraction. A `Person` `watching()` a `Television` does not need to know how the `Television` `displays()` internally or what is inside, only how to use it. – Zéychin Dec 11 '14 at 20:07
  • 1
    One thing I think ought to be clarified: the purpose of getters and setters is not to provide access to _variables_, it's to provide access to **properties** of the object, when it's important for users of an object to know about certain properties and sometimes to change them. The properties are very often implemented as private variables, which is what I think causes confusion. But I believe it's important to look them differently. A variable is part of how an object is implemented, and users should not care about the object's implementation. – ajb Dec 11 '14 at 20:31
  • Good arguments against using getters and setters by default: http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html – Weltschmerz Dec 12 '14 at 18:22

2 Answers2

10

Yes, you're right, it does effectively make the variable public. But there's one important difference, which is that it gives you the ability to change things later on: you can remove the setter if you want, or make it private, without affecting code that reads from the field using the getter.

If you'd just made the variable public, you wouldn't be able to stop writes to the field without also breaking reads from the field.

It has other advantages. You can make the access synchronized if you want to later on, without breaking client code, for instance. In short, it allows lots of modifications later on that wouldn't otherwise be possible without causing lots of breakages in code that uses the class.

And you can add extra logic that logs whenever someone writes to the field, or prevents certain threads from writing, or whatever... you can change the type of a field from a HashMap to a TreeMap if your getter abstracts it away and just returns a Map... etc.

chiastic-security
  • 20,430
  • 4
  • 39
  • 67
  • Excellent points. I didn't realize either the restrictions in flexibility of public variables like that. – AdamMc331 Dec 11 '14 at 20:40
2

Private fields are considered to be internal to the object. So the outside world doesn't need to know about how the data is stored inside the object. This means you can easily change the internal representation of data of an object while everyone else still uses the same accessors / mutators to do its work.

It's also possible that accessors / mutators perform validation and other steps that are needed internally for the object but that you don't wish to expose to code that uses the object.

You could make all fields public but that limits your ability to change the internal structure of the object later on when a lot of code now depends on a field being named a certain way.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
  • Excellent point about internal steps such as validation. Never crossed my mind. – AdamMc331 Dec 11 '14 at 20:06
  • 2
    The point about the validation and other steps is why some getters/setters should be documented (in my opinion). It is nice to know that a setX(...) won't have any other side effects or that a getX() will instantiate for me if it hasn't been already. – Aaryn Tonita Dec 11 '14 at 20:08