• A sub class has an ‘is a’ relationship with its superclass. In terms of objects, a sub class object can also be treated as a super class object. And hence, we can assign the reference of a sub class object to a super class variable type. However, the reverse is not true. A reference of a super class object may not be assigned to a sub class variable.
    Person p=new Student("Student"); // Student subclass of person
  • This ‘is a’ relationship finds application in other areas too. For example, we can pass a Student object to a method which requires a Person object and we can return a Student object from a method whose return type is Person. 
  • The methods and variables of a class that are accessible will depend on the variable type and not the object type. For example, if we try to access marks variables or the displayGrade() method of the Student object p above, we receive compilation errors. This is because, the accessible methods and variables are determined by the type of the variable and not the type of the object. 
    p.marks=100; // error
    p.showGrades(); //errors
  • The methods that can be called on a particular object referred to by a variable are decided by the data type of the variable. In this example printDetails() method has been invoked on the Student object which is referred to by a Person variable p. Hence, the call would be resolved to the printDetails() method defined in the Person class during compile time, known as static binding which occurs during compile time. However, the actual version of the method to be called is decided during run time (dynamic binding or runtime polymorphism). If the super class variable holds a reference to a sub class object, the method calls to overridden methods would be resolved to the versions defined in the sub class. If no overridden version exists for the method, then the call is resolved to the super class’ method. 
    Person p=new Student("Sai", 12, 100);
    p.printDetails();
  • However dynamic binding doesn’t happen in the case of instance variables. Suppose, we have two variables both named var, one in the super class and in the sub class. If we access this variable through a super class variable holding a reference to a sub class object, we get the value corresponding to the super class variable and not the sub class variable.
  • Just as we cast primitive data items, we can also cast reference data items to a different class type. Here too, the concepts of up casting, down casting, explicit casting and implicit casting come into picture. Implicit casting is performed in situations where we assign the reference of a sub class object to a super class variable, pass a sub class object reference to a method where a super class object is required or return a sub class object when a super class return is specified. In all these cases since a lower data type is converted to a higher data type, it is an up casting operation. Super classes are higher data types and sub classes are lower data types.

    We may also perform explicit casting, using the cast operator as shown below.
    Student s= (Student) p;

    The above statement casts into to a Student type. Now p and s refer to the same object and hence, changes made to the object through any one of the objects are reflected on the other. When we cast objects from one type to another, the compatibility of these types is checked. For example, a Student object cannot be cast to String type as they are incompatible.

Related Posts :-