BIG
DATA

JAVA

POLYMORPHISM IN JAVA WITH EXAMPLES

Read more about »
  • Java 9 features
  • Read about Hadoop
  • Read about Storm
  • Read about Storm
 

Polymorphism is an object-oriented programming concept that refers to the ability of a variable, function or object to take on multiple forms. A language that features polymorphism allows developers to program in the general rather than program in the specific.

As an example, let us assume there is a base class named Animals from which the subclasses Horse, Fish and Bird are derived. Let us also assume that the Animals class has a function named Move, which is inherited by all subclasses mentioned. With polymorphism, each subclass may have its own way of implementing the function. So, for example, when the Move function is called in an object of the Horse class, the function might respond by displaying trotting on the screen. On the other hand, when the same function is called in an object of the Fish class, swimming might be displayed on the screen. In the case of a Bird object, it may be flying.

In effect, polymorphism trims down the work of the developer because he can now create a sort of general class with all the attributes and behaviors that he envisions for it. When the time comes for the developer to create more specific subclasses with certain unique attributes and behaviors, the developer can simply alter code in the specific portions where the behaviors will differ. All other portions of the code can be left as is.

Definition

Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.

Polymorphism is the process of exhibiting multiple actions with only one interface. Infact everything around us exhibit polymorphism in one way or another.
The best example is the GOOGLE Search Engine. There is just one search Textbox which you can use to search for everything. You can search for "Wolverine 2013 movie" or "Objective Questions on Core Java" and it would present the related pages. There is NO SEPARATE SEARCH BOX for each category and thus "One Interface multiple Actions"!!

In object-oriented programming, polymorphism refers to a programming language's ability to process objects differently depending on their data type or class. More specifically, it is the ability to redefine methods for derived classes.

Any Java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all Java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object.

It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared, the type of a reference variable cannot be changed.
The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object. A reference variable can refer to any object of its declared type or any subtype of its declared type. A reference variable can be declared as a class or interface type.



Example

Let us look at an example.

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

Now, the Deer class is considered to be polymorphic since this has multiple inheritance. Following are true for the above example:

  • A Deer IS-A Animal
  • A Deer IS-A Vegetarian
  • A Deer IS-A Deer
  • A Deer IS-A Object

When we apply the reference variable facts to a Deer object reference, the following declarations are legal:

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

All the reference variables d,a,v,o refer to the same Deer object in the heap.

Real-world example

  • The best example is the GOOGLE Search Engine. There is just one search Textbox which you can use to search for everything. You can search for "Wolverine 2013 movie" or "Objective Questions on Core Java" and it would present the related pages. There is NO SEPARATE SEARCH BOX for each category and thus "One Interface multiple Actions"!!
  • On/Off switch for your house lights is dramatically different from the on/off switch for your computer. Polymorphism in this case involves two same-named items (on/off switches) performing the same task (turning something on or off), despite being very different internally.
  • A door to a temple, a door to a house, a door to a kitty house, all are doors, but all look different
  • A Teacher behaves to student. A Teacher behaves to his/her seniors. Here teacher is an object but attitude is different in different situation.
  • Person behaves SON in house at the same time that person behaves EMPLOYEE in office.
  • Your mobile phone, one name but many forms →
    • As phone
    • As camera
    • As mp3 player
    • As radio
  • A Person who knows more than two languages he can speak in a language which he knows. Here person is Object and speak is polymorphisam.


Polymorphism is essentially considered into two versions:
[1] Compile time polymorphism (static binding or method overloading)
[2] Runtime polymorphism (dynamic binding or method overriding)

Compile time Polymorphism

In this, method to be invoked is determined at the compile time. Compile time polymorphism is supported through the method overloading concept.Method overloading means having multiple methods with same name but with different signature (number, type and order of parameters).
In simple terms we can say that a class can have more than one methods with same name but with different number of arguments or different types of arguments or both.

Method Overloading

In method overloading, an object can have two or more methods with same name, BUT, with their method parameters different. These parameters may be different on two basis:
[1] Parameter type: Type of method parameters can be different. e.g. java.util.Math.max() function comes with following versions:

public static double Math.max(double a, double b){..}
public static float Math.max(float a, float b){..}
public static int Math.max(int a, int b){..}
public static long Math.max(long a, long b){..}

The actual method to be called is decided on compile time based on parameters passed to function in program.
[2] Parameter count: Functions accepting different number of parameters. e.g. in employee management application, a factory can have these methods:

EmployeeFactory.create(String firstName, String lastName){...}
EmployeeFactory.create(Integer id, String firstName, String lastName){...}

Both methods have same name 'create' but actual method invoked will be based on parameters passed in program.

Example

class X
{
   void methodA(int num)
   {
       System.out.println ("methodA:" + num);
   }
   void methodA(int num1, int num2)
   {
       System.out.println ("methodA:" + num1 + "," + num2);
   }
   double methodA(double num) {
       System.out.println("methodA:" + num);
       return num;
   }
}
class Y
{
   public static void main (String args [])
   {
       X Obj = new X();
       double result;
       Obj.methodA(20);
       Obj.methodA(20, 30);
       result = Obj.methodA(5.5);
       System.out.println("Answer is:" + result);
   }
}
Output:
methodA:20
methodA:20,30
methodA:5.5
Answer is:5.5

As you can see in the above example that the class has three variance of methodA or we can say methodA is polymorphic in nature since it is having three different forms. In such scenario, compiler is able to figure out the method call at compile-time that's the reason it is known as compile time polymorphism.

[Note]:Another term operator overloading is also there, e.g. '+' operator can be used to add two integers as well as concat two sub-strings. Well, this is the only available support for operator overloading in java, and you can not have your own custom defined operator overloading in java.

Method Overloading Rules

Here are the rules which you keep in mind while overloading any method in java:

  • First and important rule to overload a method in java is to change method signature. Method signature is made of number of arguments, type of arguments and order of arguments if they are of different types.
    public class DemoClass {
        // Overloaded method
        public Integer sum(Integer a, Integer b) {
            return a + b;
        }
     
        // Overloading method
        public Integer sum(Float a, Integer b) {  //Valid
            return null;
        }
    }
    
  • Return type of method is never part of method signature, so only changing the return type of method does not amount to method overloading.
    public class DemoClass {
        // Overloaded method
        public Integer sum(Integer a, Integer b) {
            return a + b;
        }
     
        // Overloading method
        public Float sum(Integer a, Integer b) {     //Not valid; Compile time error
            return null;
        }
    }
    
  • Thrown exceptions from methods are also not considered when overloading a method. So your overloaded method throws the same exception, a different exception or it simply does no throw any exception; no effect at all on method loading.
    public class DemoClass {
        // Overloaded method
        public Integer sum(Integer a, Integer b) throws NullPointerException{
            return a + b;
        }
     
        // Overloading method
        public Integer sum(Integer a, Integer b) throws Exception{  //Not valid; Compile time error
            return null;
        }
    }
    


Runtime Polymorphism

In this, the method to be invoked is determined at the run time. The example of run time polymorphism is method overriding. When a subclass contains a method with the same name and signature as in the super class then it is called as method overriding.

Method overriding

Declaring a method in subclass which is already present in parent class is known as method overriding.

Method overriding, in object oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class. The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed. Some languages allow a programmer to prevent a method from being overridden.

Method overriding is a perfect example of runtime polymorphism. In this kind of polymorphism, reference of class X can hold object of class X or an object of any sub classes of class X. For e.g. if class Y extends class X then both of the following statements are valid:

Y obj = new Y();
//Parent class reference can be assigned to child object
X obj = new Y();

Advantage of method overriding
The main advantage of method overriding is that the class can give its own specific implementation to a inherited method without even modifying the parent class(base class)



why method overriding

Let's see what problem we may face in the program if we don't use method overriding.

class Animal{  
	void run(){
		System.out.println("Animal is running");
	}  
}
  
class Tiger extends Animal{   
}
 
class Demo{
	public static void main(String args[]){  
	Tiger obj = new Tiger();  
	obj.run();  
	} 
}
Output:
Animal is running
But I want to provide a specific implementation of run() method in subclasses. For that reason we go for method overriding.
Lets check it out:
We will modify above program by defining the run method in the subclass as defined in the parent class but it has some specific implementation. The name and parameter of the method is same and there is IS-A relationship between the classes, so there is method overriding.
class Animal{  
	void run(){
		System.out.println("Animal is running");
	}  
} 
 
class Tiger extends Animal{
	void run(){
		System.out.println("Tiger is running");
	}     
} 

class Demo{
	public static void main(String args[]){  
	Tiger obj = new Tiger();  
	obj.run();  
	} 
}
Output:
Tiger is running

Since in method overriding both the classes(base class and child class) have same method, compile doesn't figure out which method to call at compile-time. In this case JVM(java virtual machine) decides which method to call at runtime that's why it is known as runtime or dynamic polymorphism.



Coding examples

Lets see some examples to understand method overriding better.

public class X
{
    public void methodA() //Base class method
    {
        System.out.println ("hello, I'm methodA of class X");
    }
}
public class Y extends X
{
    public void methodA() //Derived Class method
    {
        System.out.println ("hello, I'm methodA of class Y");
    }
}
public class Z
{
   public static void main (String args []) {
       X obj1 = new X(); // Reference and object X
       X obj2 = new Y(); // X reference but Y object
       obj1.methodA();
       obj2.methodA();
   }
}
Output:
hello, I'm methodA of class X
hello, I'm methodA of class Y

As you can see the methodA has different-2 forms in child and parent class thus we can say methodA here is polymorphic.

Lets have one more example.

public class Animal {
    public void makeNoise()
    {
        System.out.println("Some sound");
    }
}
class Dog extends Animal{
    public void makeNoise()
    {
        System.out.println("Bark");
    }
}
class Cat extends Animal{
    public void makeNoise()
    {
        System.out.println("Meow");
    }
}
Now which makeNoise() method will be called, depends on type of actual instance created on runtime e.g.
public class Demo
{
    public static void main(String[] args) {
        Animal a1 = new Cat();
        a1.makeNoise(); //Prints Meow
         
        Animal a2 = new Dog();
        a2.makeNoise(); //Prints Bark
    }
}

Output:

Meow
Bark


Method Overriding Rules
  • The method argument list in overridden and overriding methods must be exactly same If they don't match, you will end up with an overloaded method. The data types of the arguments and their sequence should be maintained as it is in the overriding method.
  • Overriding method (method of child class) can throw any unchecked exceptions, regardless of whether the overridden method(method of parent class) throws any exception or not. However the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. For example if overridden method throws IOException or ClassNotfoundException, which are checked Exception, than overriding method can not throw java.lang.Exception because it comes higher in type hierarchy (it's super class of IOException and ClassNotFoundExcepiton).
  • Overriding method can not reduce access of overridden method. The Access Modifier of the overriding method (method of subclass) cannot be more restrictive than the overridden method of parent class. For e.g. if the Access Modifier of base class method is public then the overriding method (child class method ) cannot have private, protected and default Access modifier as all of the three are more restrictive than public.
  • private, static and final methods cannot be overridden as they are local to the class. However static methods can be re-declared in the sub class, in this case the sub-class method would act differently and will have nothing to do with the same static method of parent class.
  • If a class is extending an abstract class or implementing an interface then it has to override all the abstract methods unless the class itself is a abstract class.
  • Return type of overriding method must be same as overridden method. Trying to change return type of method in child class will throw compile time error.


Difference between Overloading and Overriding

  • Overloading happens at compile-time while Overriding happens at runtime: The binding of overloaded method call to its definition has happens at compile-time however binding of overridden method call to its definition happens at runtime.
  • Overloading is performed within a class while overriding occurs in two or more classes that have IS-A relationship. Overriding is all about giving a specific implementation to the inherited method of parent class.
  • In case of method overloading parameter must be different. But in method overriding parameter must be same.
  • Static methods can be overloaded but cannot be overridden, even if you declare a same static method in child class it has nothing to do with the same method of parent class.
  • Performance: Overloading gives better performance compared to overriding. The reason is that the binding of overridden methods is being done at runtime.
  • private and final methods can be overloaded but they cannot be overridden.
  • Return type of overloaded methods should be same however in case of method overriding the return type of overriding method can be different from overridden method.