Site icon Experiences Unlimited

Runtime Polymorphism in Java

Quite a long time back I had written about Overriding v/s Hiding. In this post I would like to explain in brief with examples about Runtime polymorphism in Java. This post should have been written before Overriding v/s Hiding, but better late than never.

Let us consider the following Vehicle and Car and Truck class:

class Vehicle{
  public void drive(){
    System.out.println("Driving vehicle ...");
  }
}

class Car extends Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving car...");
  }
}

class Truck extends Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving truck...");
  }
  
  public void load(){
    System.out.println("Loading truck...");
  }
}

A Vehicle can be driven, so is a Car and Truck. But in addition to this a Truck can also be loaded with goods. Let us create instances of these classes and drive() them and try to also load() the truck.

public class RunTimePolymorphismDemo {
  public static void main(String[] args) {
    Vehicle vehicle = new Vehicle();
    vehicle.drive();
    
    Vehicle carVehicle = new Car();
    carVehicle.drive();
    
    Vehicle truckVehicle = new Truck();
    truckVehicle.drive();
    
    //Compile time error
    //truckVehicle.load();
    
    Truck truck = new Truck();
    truck.load();
  }
}

And the output is:

Driving vehicle ...
Driving car...
Driving truck...
Loading truck...

Had the runtime polymorphism not kicked in, the output would have been: Driving vehicle ... for all the three invocations of drive() method. You can also see that truckVehicle.drive() results in a compile time error. So what’s happening in the above code?

Any object declaration and instantiation has 2 parts in it: The type of the reference and the type of the object created. For example in Vehicle carVehicle = new Car() the reference type is Vehicle and the object created is of type Car. Such an assignment is only possible when the object created type is a subclass of the reference type i.e in cases where inheritance is used.

Each object reference can be used to invoke methods and the methods which can be invoked is decided based on the reference type. And this is decided during the compile time. But the implementation to be invoked is decided based on the type of the object created. In the above example: carVehicle.drive() compiles because the drive() method is part of the Vehicle class and gives Driving car... as the output because the method is overridden by the Car class. On similar lines: truckVehicle.load() gives compile time error because the method load() is not part of the Vehicle class, but is defined only in the Truck class. But the truck.load() compiles because the reference type is Truck class and the compiler can resolve the load() method.

To summarise:

There are plenty of places where runtime polymorphism is leveraged, few which I can state: Dependency Injection, Coding to Interface.

Exit mobile version