Polymorphism In Java With Example

Polymorphism means one name and many duties. Polymorphism refers to the ability of one thing to take many(Poly) distinct forms(Morphism). It is the property by which same message is send to objects of different classes and the objects behave differently. It is a very powerful concept that allows the designing of amazingly flexible applications.

Polymorphism can be defined as the ability to use the same for two or more related but technically different tasks. In other words, polymorphism can be defined as interface that can be used to perform related but different tasks.


Types of Polymorphism

There are two types of polymorphism:

  1. Compile time polymorphism
  2. Run time polymorphism

Compile Time Polymorphism:

Whenever an object is bound with their functionality at compile time this is known as compile time polymorphism. At compile time, java knows which method to call by checking the method signatures. So this is called compile time polymorphism or static or early binding.

Implementation of Compile time polymorphism:

Compile time polymorphism is achieved through method overloading. Method Overloading says you can have more than one function with a same name in one class having a different prototype. Function overloading is one of the way to achieve polymorphism but it depends on technology that which type of polymorphism we adopt. In java we achieve function overloading at run time.

Program Example of Compile time polymorphism:

Let us take an example to show the working of compile time polymorphism through function overloading.

Step 1: First we create a class Addition in which we declare three add() methods with different parameters:

class Addition
{

   public int add(int m,int n)
   {

      return m+n;
   }

   public int add(int m,int n,int o)
   {

     return m+n+o;
   }

   public int add(int m,double n)
   {

     return m+(int)n;
   }

}

Step 2: Second we create a class PrintAdd in which we call the above class methods by creating an object:

class PrintAdd
{

  public static void main(String args[])
  {

     Addition a=new Addition();

    System.out.println(a.add(2,3));

    System.out.println(a.add(2,3,4));

    System.out.println(a.add(2,3.4));
  }

}

Output:

5
9
5

Explanation of Example:

In above example there are three versions of add methods. The first method takes two parameters or arguments while the second one takes three parameters. In the third method there is change in type of parameters. The compiler looks at the method signature and decides which method to call for a particular method call at compile time.

Run Time Polymorphism:

Whenever an object is bound with the functionality at run time, this is known as runtime polymorphism. You can have a method in subclass that overrides the method in its parent classes with the same name and parameters. Java virtual machine determines the proper method to call at the runtime, not at the compile time. It is also called dynamic or late binding.

Implementation of Run time polymorphism:

Run time or dynamic polymorphism is achieved(implemented) through method overriding. Method overriding says child class has the same method as declared in the parent class. It means if child class provides the specific implementation of the method that has been provided by one of its parent class then it is known as method overriding.

Program Example of Run time polymorphism:

Let us take an example to show the working of run time polymorphism through method overriding.

Step 1: First we create a class Vehicle in which we declare a move() method:

class Vehicle
{

  public void move()
  {

    System.out.println("vehicles can move");
  }

}

Step 2: Second we create a class Bike which extends the class Vehicle:

class Bike extends Vehicle
{

  public void move()
  {

    System.out.println("bike can move and accelerate too");
  }

}

Step 3: Third we create a class TestVehicle in which we create an object and call the above class method:

class TestVehicle
{

  public static void main(String args[])
  {

    Vehicle v=new Bike();

    v.move();

    Vehicle v1=new Vehicle();

    v1.move();

  }

}

Output:

Bike can move and accelerate too
Vehicles can move

Explanation:

In above example, it should be noted that in the first call to move(),the reference type is Vehicle and the object is being referenced is Bike. So when a call to move() is made, java waits until runtime to check which object is being pointed to by reference. In this case,the object is of class Bike. So the move() method of Bike class will be called. In the second call to move(),the object is of class Vehicle. So the move() method of Vehicle will be called.


Difference Between Compile Time and Run Time Polymorphism

Compile time polymorphism:

  1. In compile time polymorphism, call is resolved by the compiler.
  2. It is also known as static or early binding.
  3. It is achieved by function overloading and operator overloading.
  4. It provides fast execution because known early at compile time.
  5. Compile time polymorphism is less flexible as all things execute at compile time.

 Run time polymorphism :

  1. In run time polymorphism, call is not resolved by the compiler.
  2. It is also known as dynamic binding or late binding.
  3. It is achieved by virtual functions.
  4. It provides slow execution as compare to early binding because it is known as runtime.
  5. Run time polymorphism is more flexible as all things execute at run time.

Importance of Polymorphism

  • It reduces the complexity of the object.
  • Through polymorphism complete implementation can be replaced by using same method signatures.
  • It reduces the volume of work in terms of handling various objects.

Polymorphism Important Points To Remember

  • Java does not support operator overloading directly.
  • Java does not support compile time polymorphism.
  • Access specifiers and access modifiers do not play any role in case of function overloading.
  • If you want to keep number of arguments in each function same and still you want to overload them, then change the data type of their arguments.
  • If a function is returning the value then it is not mandatory to catch the return value while calling it.
  • Return type of a function does not play any role in case of function overloading.
  • Function overloading can only be achieved by changing only in arguments.