Inheritance Nuances

  • Distinguish accessibility from the inheritance of private properties.

Consider the following code snippet

Student john = new Student("John Doe", "john@email.com");
GradStudent jane = new GradStudent("Jane Doe", "jane@email.com");
System.out.println(jane.getName() + " and " + john.getName());

Exercise What is printed out?

(a) Jane Doe and John Doe
(b) Jane Doe and Jane Doe
(c) null and John Doe
(d) and John Doe

Solution

The correct answer is (a). Note that:

  • The private fields/methods are inherited, so jane indeed has a name field with the value "Jane Doe."
  • john and jane are two separate objects - the use of the super keyword to invoke the constructor of Student in GradStudent's constructor does not link the objects of these two classes to one another.

Consider adding the following method to the GradStudent class, which raises the compilation error "name has private access in Student."

public String toString() {
    return name + " " + email;
}

Exercise How can we resolve the compilation error? (There may be more than one correct answer!)

(a) you need to use super.name and super.email instead
(b) you need to use super(name) and super(email) instead
(c) private fields/methods are not inherited so you cannot access them
(d) you need to use getName() and getEmail() instead
(e) you must change the visibility of name and email from private to protected or public in Student class

Solution

The correct answers are (d) and (e), with a preference for doing (d) over (e).

Are private fields/methods inherited? Yes! A sub-class inherits everything from its super-class. However, the inherited fields (or methods) that are declared private in a super-class are not directly accessible in sub-classes.

Declare a property with a visibility modifier of protected if you want to access it directly in derived classes. The protected modifier indicates that the property is visible to sub-classes but hidden from clients. Please use the protected modifier sparingly and only when it is needed. For fields, particularly, you don't need direct access in most cases. Therefore, you are better off using getters/setters to access them.

Resources