Apparent vs. Actual Type

Consider the following statement:

Student jane = new GradStudent("Jane", "jan@e.mail");

Notice jane is declared as Student but instantiated using GradStudent. We can break the statement into two statements for clarity:

Student jane;  // Declare jane's type is "Student"
// Then, instantiate it as GradStudent
jane = new GradStudent("Jane", "jan@e.mail");

The disparity between the types is allowed (as long as GradStudent is a subtype of Student). However, how shall we answer the question: what is jane's data type?

To answer this question, we need to make a distinction between the apparent vs. actual type of an object:

  • When you declare a variable (SomeClass obj), you are setting its apparent type to be the declared type.

  • When you instantiate an object (obj = new SomeClass()) you are setting its actual type to be the instantiated type.

Therefore, the apparent type of jane is Student, while the actual type of jane is GradStudent.

The type substitution allows the actual type of an object to be a subtype of its apparent type.

Exercise Suppose we declared Student jane and GradStudent john. Which of the following are not valid Java statements? (there may be more than one correct answer)

(a) jane = new Student("Jane", "jan@e.mail");
(b) jane = new GradStudent("Jane", "jan@e.mail");
(c) john = new GradStudent("John", "john@e.mail");
(d) john = new Student("John", "john@e.mail");

Solution

All statements are valid except for (d) which is invalid because in Java the apparent type of an object cannot be a subtype of its actual type..

Note: The apparent type determines what the object can do, while the actual type determines how the object will behave.

To understand the above statement, we must explore another pillar of object-oriented programming: polymorphism.