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 aname
field with the value "Jane Doe." john
andjane
are two separate objects - the use of thesuper
keyword to invoke the constructor ofStudent
inGradStudent
'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
- Baeldung has a great article on Java Access Modifiers.
- Oracles Java Tutorials on Controlling Access to Members of a Class
- This discussion on StackOverflow is interesting.