OOP 8. Visibility and Coupling
- Reduce visibility to reduce coupling.
- The visibility options: package,
public
,private
,protected
.
- Declare fields private, except for very simple value classes. Exceptions should be rare.
- Most methods will not be private.
Reduce coupling
To achieve the best encapsulation (information hiding) you should always declare methods with the least visibility that works. In small programs there's really no problem, but in large programs this problem of excessive coupling is very serious. Coupling occurs when one part depends on the specific implementation of another. The more coupling there is the more costly it becomes to make changes because too much code depends on specific implementations. This causes software rot - a program becomes progressively less usable because it can't be easily upgraded.
Visibility - public
, private
, or package
private
- This should always be your first choice for instance variables. It is rare for an instance variable to have any permission exceptprivate
. All instance methods in the same class can use a private instance variable, but no methods in other classes can even see it. Communication between classes should be by means of methods, not variables, so methods will normally not be private.- default (package) - If you don't specify anything, the default visibility allows classes in the same package (directory) to see it. This is a good, and common, choice for classes and methods, but should not be used for instance variables, which should be private.
public
- Let's anyone see it. Choose this if you've defined a method that will be used by others outside of your project. Note thatmain
is the only method that must be declaredpublic
so the run-time system can see it and call it.protected
- Only use this after careful thought. See optional discussion below.
protected
and why you might avoid it (Optional)
There is substantial controversy about whether protected
visibility
should be used. It is like private
, but additionally
grants visibility to child classes.
One problem is that anyone can make a child class which can reference it. If someone has access to your class, they can make this variable or method effectively public by supplying a getter and setter for it.
There is protection against casual access, but not against anyone who feels a real need to access private data/methods. Perhaps its main use is in making anyone who is thinking about using protected variables/methods think a little more about it.
Protected access also encourages coupling between the parent and child class, as with all inheritance. This coupling can prevent improvements or changes to the parent class, and should be discouraged.
Using protected access is only useful if you've designed your class so that others can extend it. Designing for inheritance is not trivial because you have to imagine all the ways it might be used. I believe Elliotte Rusty Harold (Java book author) offered the opinion that designing for inheritance takes about three times as much work as not allowing inheritance! For example, if the user wanted to use it in a Map, you did override hashcode(), didn't you? Of course, if it's for your own use, you'll be able to fix things easily.