Polymorphism

Polymorphism is a feature of OOPs. Polymorphism is a feature that allows one interface to be used for a general class of actions. Polymorphism performs a single step in different ways. polymorphism Greek, meaning ―many forms.

In Java, we can specify a general set of stack routines that all share the same names. The concept of polymorphism is often expressed by the phrase ―one interface, multiple methods. This means that it is possible to design a generic interface to a group of related activities. This helps reduce complexity by allowing the same interface to specify a general class of action.

Polymorphism allows us to create a clean, sensible, readable, and resilient code.

Polymorphism has two types in Java: Compile time polymorphism (static binding) and Runtime polymorphism (dynamic binding). Method overloading is an example of static polymorphism, whereas method overriding is an example of dynamic polymorphism.

Compile-time Polymorphism

Compile-time Polymorphism is also called “Static polymorphism”. In Compile-time Polymorphism, whatever it performed is performed at compile time.

Compile-time Polymorphism is implemented by operator overloading and function overloading. In Compile-time Polymorphism, one of the most common implementations is method overloading.

Example of compile time polymorphism
		class MethodOverloadingExample {
			 void method1(int x)
			{
				System.out.println("Integer: "+x);
			}
			 void method1(double y)
			{
				System.out.println("Double "+y);
			}
			 void method1(int x, int y)
			{
				System.out.println("Integer x and y:"+x+" "+y);
			}
			public static void main(String args[])
			{
				MethodOverloadingExample moe=new MethodOverloadingExample();
				moe.method1(10);
				moe.method1(20.0);
				moe.method1(10, 20);
			}
		}
Output

Integer: 10

Double: 20.0

Integer x and y:10 20

Example 2 for compile-time polymorphism
		class Overload
		{
		    void demo (int x)
		    {
		       System.out.println ("x: " + x);
		    }
		    void demo (int x, int y)
		    {
		       System.out.println ("x and y: " + x + "," + y);
		    }
		    double demo(double x) {
		       System.out.println("double x: " + x);
		       return x*x;
		    }
		}
		class MethodOverloading
		{
		    public static void main (String args [])
		    {
		        Overload Obj = new Overload();
		        double result;
		        Obj .demo(10);
		        Obj .demo(10, 20);
		        result = Obj .demo(5.5);
		        System.out.println("O/P : " + result);
		    }
		}
Output

x: 10

x and y: 10,20

double x: 5.5

O/P : 30.25

In above Example, the method demo() is overloaded three times: first method has one int parameter, second method has two int parameters and third one has a double parameter. Which method is to be called is determined by the arguments we pass while calling methods. This happens at compile time so this type of polymorphism is known as compile time polymorphism.

Runtime Polymorphism

Runtime Polymorphism which is also known as dynamic polymorphism. In Java Runtime Polymorphism is resolve by using “Method overriding”.

In Method overriding, method in parent class can redefine or overridden in child class. When method is overridden in child class, then the dynamic method dispatch technique can determine the overridden method call at run time.

Advantages of Runtime Polymorphism
  • The program is allowed to override methods in rum time polymorphism.
  • In run time polymorphism it provides classes to define a method with general implementation which its derivatives can then override and provide the specific implementation.
  • In run time polymorphism, call of method is resolved in runtime whereas overloading is decided at compile time. This provides flexibility to programmers.
Example of Runtime Polymorphism
		class Shape {
		 	 void draw()
			{
				System.out.println("Draw Shape");
			}
			public static void main(String[] args) {
				Shape s=new Square();
				s.draw();
				s=new Circle();
				s.draw();
			}
		}
		class Square extends Shape
		{
			 void draw()
			{
				System.out.println("Draw Square");
			}
		}
		class Circle extends Shape
		{
			 void draw()
			{
				System.out.println("Draw Circle");
			}
		}
Output

Draw Square

Draw Circle

In the above example, parent class have Shape and child class as Square and circle. We are assigning child object to the parent object. We have overridden draw methods in a child as Square and Circle. JVM decides at runtime which method it needs to call depending on the object assignment.

Java Runtime Polymorphism Example: Office
		class Office{  
		int getSalary(){return 0;}  
		}
		class Developer extends Office{  
		int getSalary(){return 50000;}  
		}
		class Trainer extends Office{  
		int getSalary(){return 40000;}  
		}
		class HR extends Office{  
		int getSalary(){return 25000;}  
		}
		class TestPolymorphism{  
		public static void main(String args[]){  
		Office o;  
		o=new Developer();  
		System.out.println("Developer Salary: "+o.getSalary());  
		o=new Trainer();  
		System.out.println("Trainer Salary: "+o.getSalary());  
		o=new HR();  
		System.out.println("HR Salary: "+o.getSalary());  
		}
		}
Output

Developer Salary: 50000

Trainer Salary: 40000

HR Salary: 25000

In the above example, Assume there is an Office in a class that provides a salary method. However, salary may differ according to their designations. For example, Developer, Trainer, and HR are providing 50000, 40000, and 25000 salary.

Copyright 1999- Ducat Creative, All rights reserved.