How to refer a subclass object
There are two approaches to refer a subclass object:
- using the subclass reference: a subclass reference can be used to refer its object;
- using the superclass reference: a reference variable of a superclass can be used to a refer any subclass object derived from that superclass, because the subclass is a special case of the superclass.
Let's consider an example of person hierarchy explaining both the approaches.
class Person {
protected String name;
protected int yearOfBirth;
protected String address;
// public getters and setters for all fields
}
class Client extends Person {
protected String contractNumber;
protected boolean gold;
// public getters and setters for all fields
}
class Employee extends Person {
protected Date startDate;
protected Long salary;
// public getters and setters for all fields
}
As you know, each of the presented class has the default no-args constructor.
1. Subclass reference example. We can create instances of the subclasses using the constructor:
Person person = new Person(); // the reference is Person, the object is Person
Client client = new Client(); // the reference is Client, the object is Client
Employee employee = new Employee(); // the reference is Employee, the object is Employee
In this case, we used the subclass references because the types of references are the same as the types of the created objects.
2. Superclass reference example. We can create instances of the subclasses using the constructor:
But we can also declare a reference to the superclass and refer a subclass object using the reference:
Person client = new Client(); // the reference is Person, the object is Client
Person employee = new Employee(); // the reference is Person, the object is Employee
In this case, we used the superclass reference because the types of references have the type of the superclass and the types of actually created objects are subclasses.
Remember:
- you cannot assign an object of one subclass to the reference of the other subclass and vice versa because they don't inherit each other:
Client whoIsIt = new Employee(); // it's impossible
- you cannot assign an object of the parent class to the reference of its subclass:
Client client = new Person(); // it's impossible too
The common rule: If class A is a superclass of class B and class B is a superclass of class C then in that case, variable of class A can reference any object derived from that class (i.e. object of class B and class C). This is possible because each subclass object is an object of its superclass but not vice versa.
Accessing fields and methods through a superclass reference
So, we can use a superclass reference to hold any subclass object derived from it. But we cannot access subclass specific members through the base class reference. We have access only to those members of the object defined by the type of reference.
Example. In the considered hierarchy we mean each class has getters and setters to access protected field from the outside.
Person employee = new Employee();
employee.setName("Ginger R. Lee"); // Ok
employee.setYearOfBirth(1980); // Ok
employee.setSalary(30000); // Compile-time error, the base class "doesn't known" about the method
The superclass
Person
"doesn't have" the method setSalary
of the class Employee
. You cannot invoke the method through the superclass reference. The same rule works for fields as well.Casting between superclass and subclass
You can always cast an object of a subclass to its superclass. Also, it may be possible to cast an object from a superclass type to a subclass, but only of the object really is an instance of this subclass, otherwise ClassCastException will be thrown. Be careful when casting a class to its subclass.
Person person = new Client();
Client clientAgain = (Client) person; // it's ok
Employee employee = (Employee) person; // the ClassCastException occures here
After the successful casting a superclass to a subclass, we can access members of it.