Private vs Protected - Visibility Good-Practice Concern

Madara's Ghost picture Madara's Ghost · Dec 2, 2011 · Viewed 111.8k times · Source

I've been searching and I know the theoretic difference.

  • public - Any class/function may access the method/property.
  • protected - Only this class and any subclasses may access the method/property.
  • private - Only this class may access the method/property. It won't even be inherited.

That's all fine and well, the question is, what's the practical difference between them? When would you use private and when would you use protected? Is there a standard or acceptable good practice over this one?

Up until now, to retain the concept of inheritance and polymorphism, I use public for anything that should be accessed from the outside (like constructors and main class functionality), and protected for internal methods (logic, helper methods etc). Am I on the right track?

(Note that this question is for me, but also for future reference as I haven't seen a question like this one SO).

Answer

JB Nizet picture JB Nizet · Dec 2, 2011

No, you're not on the right track. A good rule of thumb is: make everything as private as possible. This makes your class more encapsulated, and allows for changing the internals of the class without affecting the code using your class.

If you design your class to be inheritable, then carefully choose what may be overridden and accessible from subclasses, and make that protected (and final, talking of Java, if you want to make it accessible but not overridable). But be aware that, as soon as you accept to have subclasses of your class, and there is a protected field or method, this field or method is part of the public API of the class, and may not be changed later without breaking subclasses.

A class that is not intended to be inherited should be made final (in Java). You might relax some access rules (private to protected, final to non-final) for the sake of unit-testing, but then document it, and make it clear that although the method is protected, it's not supposed to be overridden.