Answer to why method overriding is called runtime polymorphism in java is because the methods get resolved at the Run-Time.
In simple words, when you execute a program, the method of which class out of many will be called, if they have overridden the method.
Let’s understand by very simple scenario with code example for your easy understanding.
- You may read more about method overriding in java.
Consider the below example,
There is a Car class and its two subclasses Maruti and Hyundai. Both the subclasses have overridden the run() method of the base class Car.
class Car {
public void run() {
System.out.println("running…");
}
}
class Maruti extends Car {
public void run() {
System.out.println("Maruti running...");
}
}
class Hyundai extends Car {
public void run() {
System.out.println("Hyundai running...");
}
}
There is another class Driving as below.
class Driving {
// /Here object of the car only can be known at run time
public void drive(Car c) {
c.run();
}
}
By looking at the method drive(Car c), can you tell which car object, Maruti or Hyundai will run?
NO, WE CAN NOT!!!. Hence, the JVM also cannot decide by looking at them at compile time. JVM can only decide at run time, which object Maruti or Hyundai to run. That’s why method overriding is called run time polymorphism.
NOTE:
Note that in method overloading you can tell at compile time itself which method will be called, for example, in the below class you know that f() will be called with no arguments and f(int a) will be called if we pass 1 int argument without running the program. Hence, in the case of method overloading, JVM can resolve the method at compile time itself.
class A{
//Overloading
void f(){
}
void f(int a){
}
}
Complete Code Example of Run-Time Polymorphism in Java
In the given example that you read previously, the drive(Car c) method of the Driving class will receive object of multiple types of car from the main() method, and will decide which object’s run() method to call at the run time.
The main() method will create object of Driving class and multiple types of Car objects such as Maruti and Hyundai, and will supply the objects of the cars to the drive method.
NOTE:
Main program uses base class Car reference and assign object of Maruti or Hyundai Car object. e.g. Car m = new Maruti(); // base reference and Maruti class object.
class Car {
public void run() {
System.out.println("Car running");
}
}
class Maruti extends Car {
public void run() {
System.out.println("Maruti running...");
}
}
class Hyundai extends Car {
public void run() {
System.out.println("Hyundai running...");
}
}
class Driving {
// /Here object of the car only can be known at run time
public void drive(Car c) {
c.run();
}
}
public class Sample {
public static void main(String[] args) {
Driving d = new Driving();
// supply Maruti object
Car m = new Maruti();
d.drive(m);
// supply Hyundai object
Car h = new Hyundai();
d.drive(h);
}
}
Output:
Maruti running…
Hyundai running…
NOTE:
If there is an interface and multiple derived concrete classes, who implements and override methods of interfaces, the run time effect can also be seen .
- You may want to read more about Interfaces in java.
Read the loose coupling example in java where Manager class constructor receives multiple classes and call the work() method. Workers objects are resolved at run time and call respective work() methods.