Polymorphism in Java With Examples : OOPs Concept

In this post, I will be sharing what is polymorphism in java, real-life examples of polymorphism, different types of polymorphism i.e static polymorphism (compile-time polymorphism) and dynamic method dispatch (run-time polymorphism). Before moving forward, if you do not know what is method signature and what is parameter then please read here. Now you are ready:

Read Also:  Difference between Method Overloading and Method Overriding

What is Polymorphism in Java

Polymorphism is considered as one of the core features of any Object-Oriented Programming Language. The definition of "Polymorphism" is hidden in its name itself. "Poly" means "many" and "morphs" means "forms". Thus "Polymorphism" may be considered as a concept in Java in which an entity(object), variable or function may present in one or many forms.

Real-Life Example of Polymorphism in Java

Before going towards classical definition, let’s understand the concept of polymorphism with the help of a real-life example. Consider a Smartphone. One can use a Smartphone for calling. The same device can be used to listen to music or to watch videos. So, with the help of one Smartphone, we can do several different kinds of tasks with the help of various applications. Thus it can be considered a real-life example of polymorphism.

Polymorphism In Java

Polymorphism may be defined as the ability of an entity(object) to be present in many forms. In Object-Oriented Programming, this entity is an object or any reference to the object.
For example, In Java, one object can take multiple forms depending upon the context of our program.

Let us consider we want to create a function that finds the volume of a container that is either cylindrical or cuboid in shape. Cylinder and Cuboid have a different formula for volume calculation. So, volume calculation can’t be done with the use of only one function. In such a case, we can create functions with the same name but a different method signature.

Let’s have a look over the following program:

Here, we have created one class Container. The function volume() is defined twice within the same class with different method signatures.

class Container{
    
    float length, breadth, height;
    float radius;
    
    /* Below we are calculating the Volume of
       the Cuboid */   
float volume(float l, float b, float h) { length = l; breadth = b; height = h; return length*breadth*height; }
    /* Below we are calculating the Volume of
       the Cylinder */        
float volume(float r, float h) { radius = r; height = h; return 3.14f*r*r*h; } } public class JavaHungry { public static void main(String a[]) {
        // Creating Container class object
        Container c1 = new Container();
 
        // Below we are passing 3 parameters
        float vol1 = c1.volume(1.0f,2.0f,3.2f); 
        System.out.println("Volume of Cuboid Container is : "+ vol1); 
 
        // Below we are passing 2 parameters 
        float vol2 = c1.volume(2.11f,3.6f); 
        System.out.println("Volume of Cylindrical Container is : "+ vol2);
    }
}


Output :
Volume of Cuboid Container is : 6.4
Volume of Cylindrical Container is : 50.326534


In the above program, we created the object c1 of the class Container.

3 parameters are passed while calling the volume() function on object c1. The volume() function in the Container class which had 3 parameters in the method signature is called. Thus, the volume of the cuboid is calculated.

Similarly, the same object c1 of the class Container is passed with 2 parameters. The volume() function in the Container class which had 2 parameters in the method signature is called. Thus, the volume of the cylinder is calculated.

Hence, this program exhibits Polymorphism in Java as the single object c1 is used to calculate the volume of Cylinder and volume of Cuboid.

Different Types of Polymorphism in Java

On the basis of implementation, Polymorphism may be categorized into two types:

1.    Compile Time Polymorphism
2.    Runtime Polymorphism

1. Compile Time Polymorphism:

Compile Time Polymorphism is also called as Static Polymorphism. It can be achieved with the help of Method Overloading, Constructor Overloading, and Operator Overloading. Let’s discuss each in brief:

a. Method Overloading: I have already explained the Method Overloading in detail here. In Java, it is possible for a class to have multiple methods with the same name as long as they have different signatures. Thus methods or functions having the same name can be present within a class with different signatures. This mechanism of achieving Polymorphism is called Function Overloading or Method Overloading and the functions are called Overloaded Functions.

Example:


class Overload
{
    void display()
    {
        System.out.println("No argument");
    }
    
    void display(int x)
    {
        System.out.println(x);
    }
    void display(int x, int y)
    {
        System.out.println(x+" "+y);
    }
} 

public class JavaHungry
{
    public static void main(String a[])
    {
        Overload object = new Overload();
        object.display();
        object.display(1);
        object.display(1,2);
    }
}

Output :
No argument
1
1 2

In the above example, class Overload has three function definitions of function display with the same names whereas method signatures of all these three functions are different.
The different method signatures are display(), display(int x) and display(int x, int y).

b. Constructor Overloading: I have explained the constructor overloading in detail here. The concept of constructor overloading is quite similar to Method Overloading. In Java, it is possible for a class to have multiple constructors with different signatures i.e. with different argument lists. With the help of constructor overloading, different kind of objects can be initialized.


//Constructor Overloading in Java
class Triangle
{
    Triangle()
    {
        System.out.println("No Parameters inside Constructor.");
    }
    Triangle(int equalSides)
    {
        System.out.println("Equilateral Triangle with Side Length: "+equalSides);
    }
    Triangle(int equalSides, int unequalSide)
    {
        System.out.println("Isosceles Triangle with Equal Side Length: "+equalSides);
    }
    Triangle(int firstSide, int secondSide, int thirdSide)
    {
        System.out.println("Scalene Triangle with Side Lenghts: "+firstSide+","+secondSide+","+thirdSide);
    }
}

public class JavaHungry
{
    public static void main(String a[])
    {
        Triangle t1 = new Triangle();
        Triangle t2 = new Triangle(3);
        Triangle t3 = new Triangle(2,3);
        Triangle t4 = new Triangle(1,3,5);
    }
}

Output :
No Parameters inside Constructor.
Equilateral Triangle with Side Length: 3
Isosceles Triangle with Equal Side Length: 2
Scalene Triangle with Side Lengths: 1,3,5

In the above example, the class Triangle has four constructors with the same name but different argument lists. In the JavaHungry class four different objects t1, t2, t3 and t4 are created. While creating the objects when we call the constructor, the constructor having a similar signature is invoked.

c. Operator Overloading: In Java, the same operator may be used in different forms. This is called operator overloading. For example, operator “+” is used for addition when the operands are numbers (int, float etc). It acts as a concatenation operator when operands are strings. Example of operator overloading can be seen in the following program:


public class Overload{
    public static void main(String args[])
    {
        int a=5,b=10;
        int c = a+b;
        System.out.println(a+"+"+b+" = "+c); //Addition using '+' Operator
        String s1 = "Hello", s2 = "World";
        String s3 = s1+s2; //Concatenation using '+' Operator
        System.out.println(s1+"+"+s2+" = "+s3);
    }
}

Output :
5+10 = 15
Hello+World = HelloWorld


When ‘+’ operator was used with operands as numbers, it added the operand whereas when the operands were strings, it concatenated the operands.

2. Runtime Polymorphism:

Runtime Polymorphism is often known as Dynamic Method Dispatch. This kind of polymorphism can be achieved with the help of method overriding (function overriding). Dynamic Method Dispatch is a process in which a function call to the overridden method is resolved at runtime.

a. Method Overriding: I have explained the Method Overriding in detail here. In a program, if a particular child class contains a method with the same name, same parameters and covariant return type as that of parent class then the method in child class hides the method of parent class in the child class. This mechanism is called Method Overriding and these methods are called Overridden
Methods. To access the parent class’s method in the child class, we need to use the super keyword. Method Overriding can be avoided using the final keyword.


class Parent
{
    int a = 15, b = 30;
    void display()
    {
        int c = a+b;
        System.out.println("Sum = "+c);
    }
}

class Child extends Parent
{
    void display()
    {
        super.display();
        int d = a*b;
        System.out.println("Product = " + d);
    }
}

public class JavaHungry
{
    public static void main(String args[])
    {
        Parent ob = new Child();
        ob.display();
    }
}

Output:
Sum = 45
Product = 450


In the above program, the display() method of child class overrides the display() method of a parent class. Also, In display() method of child class super keyword is used to invoke a display method of the parent class.

That's all for today, please mention in comments in case you have any questions or doubts regarding polymorphism definition, different types or polymorphism examples.

About The Author

Subham Mittal has worked in Oracle for 3 years.
Enjoyed this post? Never miss out on future posts by subscribing JavaHungry