This article explains one of the most important concepts of Object Oriented Programming, Polymorphism, with several sets of examples along with definitions and related diagrams.
Runtime Polymorphism
A process in which a call to an overridden method is resolved at runtime rather than compile time is known as Runtime Polymorphism.
It is also called Dynamic method dispatch.
The idea behind this concept is that the overridden method is called by the reference variable of the superclass, in other words the parent class. The method to be called is determined on the basis of the object being referred to by the reference variable.
Upcasting
When the reference variable of the parent class is called by the object of the child class, it is known as upcasting.
class Student {}
class Monitor extends Student{}
Student s=new Monitor(); // upcasting
Example of runtime Polymorphism
In this example, we created the two classes Car and Swift. Car is the parent, in other words the superclass and Swift is the child, in other words the subclass. The Swift class extends the Car class and overrides its methods.
We are calling the Speed method by the reference variable of the parent class. Since it refers to the subclass object of the child class and the subclass method overrides the parent class method, the subclass method is invoked at runtime.
Since the method is invoked by the JVM, not the compiler, it is called runtime polymorphism.
class Car
{
void speed()
{
System.out.println("Speed should be more than a bike");
}
}
class Swift extends Car
{
void speed()
{
System.out.println("Speed is 200km/hr.");
}
public static void main(String args[])
{
Car c=new Swift();// upcasting
c.speed();
}
}
Output
Speed is 200km/hr.
In the preceding example “c” is the reference variable. The subclass, in other words the child class method, is invoked at runtime.
Example | Runtime Polymorphism
Consider the scenario that the bike is the class that provides methods to get the top speed limit.
Companies provide varying top speeds. For example Honda-150km/hr, TVS-180km/hr, Yamaha-200km/hr.
Example | Hierarchical inheritance
This example shows the functioning of the hierarchical inheritance.
class Bike
{
int topSpeedLimit()
{
return 0;
}
}
Class Honda extends Bike
{
int topSpeedLimit()
{
return 150;
}
}
class Yamaha extends Bike
{
int topSpeedLimit()
{
return 180;
}
}
Class Tvs extends Bike
{
int topSpeedLimit()
{
return 200;
}
}
class Test
{
public static void main(String args[])
{
Bike b1=new Honda();
Bike b2=new Yamaha();
Bike b3=new Tvs();
System.out.println("Top speed of Honda:"+b1.topSpeedLimit());
System.out.println("Top speed of Yamaha:"+b2.topSpeedLimit());
System.out.println("Top speed of Tvs:"+b3.topSpeedLimit());
}
}
Output
Top speed of Honda:150
Top speed of Yamaha:180
Top speed of Tvs:200
Runtime Polymorphism can be categorized in these two parts:
Runtime Polymorphism with Data member
The method is overridden but not the data members, so runtime polymorphism cannot be done with data members.
In the example given below, we created a Student class and Monitor class. Both the classes have data members, in other words name and roll number. We are accessing the data members by the reference variable of the parent class that refers to the subclass object.
Since we are accessing the data members of the subclass that are not overridden, the data members of the parent class will always be invoked.
Class Student
{
String name="Arunesh";
}
Class Monitor extends Student
{
String name="Amrita";
public static void main(String args[])
{
Student s=new Monitor();
System.out.println(s.name);
}
}
Output: Arunesh
Runtime Polymorphism with multilevel inheritance
Let's see the simple example.
class Electronics
{
void function()
{
System.out.println("Made for various purpose");
}
}
class Phone extends Electronics
{
void function()
{
System.out.println("Display,Voice");
}
}
class Computer extends Phone
{
void function()
{
System.out.println("Calculation,Internetworking");
}
public static void main(String args[])
{
Electronics e1=new Electronics();
Electronics e2=new Phone();
Electronics e3=new Computer();
e1.function();
e2.function();
e3.function();
}
}
Output
Made for various purposes.
Display,Voice
Calculation,Internetworking
Analyze this example and try to figure out what happens here.
class Electronics
{
void function()
{
System.out.println("Made for various purpose");
}
}
class Phone extends Electronics
{
void function()
{
System.out.println("Display,Voice");
}
}
class Computer extends Phone
{
public static void main(String args[])
{
Electronics e=new Computer();
e.function();
}
}
Output: Display,Voice
Here the Computer class does not override the function() method, so the function() method of the phone class is invoked.