Access modifiers: What gives?

Do access modifiers prevent inheritance?

Q: In the Java 2 training class I'm taking, the "In Packages and Inheritance" module states:

When you create a subclass, it cannot inherit any of the superclass's methods and variables that are restricted by access modifiers.

As I understood it, the access modifier private would not prevent inheritance but would prevent access (overloading/overriding) by a subclass. Also, a subclass inherits all the methods and attributes of its superclass(es), and visibility modifiers affect this: private methods and attributes cannot be accessed in a subclass. You'd have to use protected to allow subclass access. Can you clear up my confusion?

A: You are absolutely correct. Access modifiers do not prevent inheritance. Instead, access modifiers affect what you can and cannot see in the subclass.

Those private members and attributes are still in your subclasses. Your subclasses just cannot access them directly.

Let's review the access modifiers:

  • Private members and attributes are completely hidden from outside classes as well as from subclasses.
  • Protected access hides the class's methods and attributes from classes that exist outside of the class's package. This means that classes within the same package can access protected methods and attributes. When subclassing, the class' subclasses can also access the protected methods and attributes.
  • Public methods are open for anyone to see.
  • Package protected allows access only to those classes appearing in the same package. When subclassing, only the subclasses that appear in the same package can access package protected methods and attributes.

I use the following rules of thumb to determine access levels:

  • Public: For those methods that are necessary to use an object. Note that attributes should never be public. If other objects need access to attributes, create getters and declare them as final.
  • Protected: Best reserved specifically for subclass use. I do not declare anything as protected unless I know that a subclass absolutely needs it. In general, I do not declare methods and attributes as protected in the chance that a subclass may need it sometime in the future. If my design does not justify it explicitly, I declare everything that is not in the public interface as private.
  • Private: For all methods not in the public interface and not designed for use by subclasses.
  • Package Protected: Like protected this level is best reserved specifically for subclass use. However, package protected acts more restrictive than protected. A subclass appearing outside of the class's package will not be able to access package protected features. Package protected is useful if you want to open features to your subclasses but want to restrict access to those who might not understand the full design or consequences of using a feature.

Learn more about this topic