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
Studentand store both objects ofStudentandGradStudentin it; - have one pair of
add/removemethods that take a parameter of typeStudentand invoke it by passing either an object ofStudentorGradStudent; - have one
findmethod that returns an object of typeStudentand 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).