Type Substitution
Assume Student
and GradStudent
were not linked through inheritance (i.e. they were two independent data types). To allow both grad and non-grad students to take the same course, we must update the Roster
class as follows, essentially duplicating every field and method to accommodate two types of students.
public class Roster {
private Student[] students;
private int numStudents;
private GradStudent[] gradStudents;
private int numGradStudents;
public Roster(int size) {
students = new Student[size];
gradStudents = new GradStudent[size];
numStudents = 0;
numGradStudents = 0;
}
public void add(Student s) { ... }
public void remove(Student s) { ... }
public Student find(String email) { ... }
public void addGrad(GradStudent s) { ... }
public void removeGrad(GradStudent s) { ... }
public GradStudent findGrad(String email) { ... }
}
If GradStudent
is declared as a subtype of Student
, the (original) Roster
class (as defined in the previous chapter) need no changes at all. You will be able to add/remove grad students by leveraging type substitution.
Type substitution
A variable of a given type may be assigned a value of any subtype, and a method with a parameter of a given type may be invoked with an argument of any subtype of that type.
So, since we can substitute GradStudent
for Student
we can
- have one student array of type
Student
and store both objects ofStudent
andGradStudent
in it; - have one pair of
add
/remove
methods that take a parameter of typeStudent
and invoke it by passing either an object ofStudent
orGradStudent
; - have one
find
method that returns an object of typeStudent
and use it to search both grad and non-grad students.
Exercise Can we redefine Roster
and use GradStudent
in place of Student
(in declaration of fields/parameters data types) to achieve the same effect?
Solution
Since inheritance is not symmetric, we would not be able to achieve the same effect if we were to define Roster
and use GradStudent
in place of Student
(in the declaration of fields/parameters data types).