Sunday 9 October 2016

Understanding Polymorphism in Java

Polymorphism is one of the hot topics for a java interview. Questions, based on polymorphism, are asked at every level in java interview. In java, polymorphism is achieved, when a method with same name but different body are executed under different conditions.Polymorphic method invocations apply only to instance methods. You can always refer to an object with a more general reference variable type (a superclass or interface), but at runtime, the ONLY things that are dynamically selected based on the actual object (rather than the reference type) are instance methods. In java, objects can only be accessed through reference variables. Let us see few important things regarding the reference type variables in java :

  • A reference variable can be of only one type, and once declared, that type can never be changed (although the object it references can change).
  • A reference is a variable, so it can be reassigned to other objects, (unless the reference is declared final ).
  • A reference variable's type determines the methods that can be invoked on the object the variable is referencing.
  • A reference variable can refer to any object of the same type as the declared reference, or—this is the big one—it can refer to any subtype of the declared type!
  • A reference variable can be declared as a class type or an interface type. If the variable is declared as an interface type, it can reference any object of any class that implements the interface.
In java, there are two types of Polymorphism; 1. Runtime Polymorphism(implemented through method overriding). 2. Compile-time polymorphism(implemented through method overloading).

Method Overriding

When a method with same name and same signature is present in both Super class and Sub class, then the method in the super class is called over ridden method and the method in the sub class is called overriding method.Any time you have a class that inherits a method from a superclass, you have the opportunity to override the method. The key benefit of overriding is the ability to define behavior that's specific to a particular subclass type. The following example demonstrates a Horse subclass of Animal overriding the Animal version of the eat() method:

public class Animal {
	public void eat() {
		System.out.println("Eat method of Animal Class");
	}
}
class Horse extends Animal {
	public void eat() {
		System.out.println("Eat method of Horse class");
	}
}
public class TestAnimals 
{
	public static void main (String [] args) {
		Animal a = new Animal();
		Animal b = new Horse(); //Animal ref, but a Horse object
		a.eat(); // Runs the Animal version of eat()
		b.eat(); // Runs the Horse version of eat()
	}
}

In the above example,since,the object creation occurs at run time,therefore which version of eat() to be called is decided at run time.This why it is referred to as runtime polymorphism

Method Overloading

Two methods with same,name in same class but with different signatures will be referred to as as overloaded methods.Overloaded methods let you reuse the same method name in a class, but with different arguments (and optionally, a different return type).


class SumNumber {
	public int getSum(int x, int y) {
		return x + y;
	}
	// Overload the getSum method to add doubles instead of ints
	public double getSum(double x, double y) {
		return x + y;
	}
}

public class TestSum{
	public static void main(String [] args)
	{
		SumNumber sn = new SumNumber();
		System.out.println("Sum of Integer : "+sn.getSum(10, 20));//Integer version of getSum is called
		System.out.println("Sum of Double : "+sn.getSum(10.5, 19.5));//Double version of getSum is called

	}
}

In the above example,which method of get sum is to be called is decided at compile time,based on method signature therefore it is called compile-time polymorphism

Some key take aways and rules regarding method overloading and method overriding

  • Methods can be overridden or overloaded; constructors can be overloaded but not overridden.
  • Abstract methods must be overridden by the first concrete (non-abstract) subclass.
  • With respect to the method it overrides, the overriding method
  • Must have the same argument list.
  • Must have the same return type, except that as of Java 5, the return type can be a subclass—this is known as a covariant return.
  • Must not have a more restrictive access modifier.
  • May have a less restrictive access modifier.
  • Must not throw new or broader checked exceptions.
  • May throw fewer or narrower checked exceptions, or any unchecked exception.
  • final methods cannot be overridden.
  • Only inherited methods may be overridden, and remember that private methods are not inherited.
  • A subclass uses super.overriddenMethodName() to call the superclass version of an overridden method.
  • Overloading means reusing a method name, but with different arguments.
  • Overloaded methods must have different argument lists.
  • Overloaded methods may have different return types, if argument lists are also different.
  • Overloaded methods may have different access modifiers.
  • Overloaded methods may throw different exceptions.
  • Methods from a superclass can be overloaded in a subclass.
  • Polymorphism applies to overriding, not to overloading.
  • Object type (not the reference variable's type), determines which overridden method is used at runtime.
  • Reference type determines which overloaded method will be used at compile time.

No comments:

Post a Comment