October 2003 Technical Tip – Inheritance Revisited
We saw a brief introduction to inheritance in the July 2002 issue of this newsletter. Given last month's article on composition and aggregation, it seems appropriate to revisit the issue of inheritance. Indeed, the example used in last month's article lends itself more to inheritance than to composition and aggregation. You will recall that composition is the means by which a "has a" relationship is implemented, whereas inheritance is the means by which an "is a" relationship is implemented.
Last month we saw the Student and StudentAthlete classes. We said then if we view the StudentAthlete class as "having" a Student, then composition would be appropriate. But it is probably more correct to say a StudentAthlete "is a" Student, in which case inheritance is implied. The UML diagram shown below indicates an inheritance relationship. We say the Student class is the superclass and the StudentAthlete2 class is the subclass (we will call the class StudentAthlete2 to differentiate it from last month's StudentAthlete.) In the UML a white triangle indicates inheritance, with the triangle pointing to the superclass.
The source code for the superclass can be viewed online at http://www.caliberdt.com/tips/Student.java. We will look at the source code for the subclass here:
Note the use of the keyword super. In order to create an instance of the subclass, we must first create an instance of the superclass: the line super(name, grade) looks for a constructor in the superclass which takes a String and an int as its arguments. The keyword super, if used, must be the first line in the constructor. When would it not be used? When the keyword this is used to invoke a different (overloaded) constructor of the subclass and that constructor uses super to call the constructor of the superclass.
The use of the keyword super is not limited to constructors. Note the use of super in the toString() method: we are saying the toString() method of the subclass return the same thing as the toString() method of the superclass and a little bit more. This approach ensures consistency: if we decide to change the appearance of the String in the superclass, that change would automatically be reflected in the subclass.
(Source code for the test application can be found here.)