Java Polymorphism

Java Polymorphism


Java Polymorphism

  • Polymorphism (from Greek, meaning “many forms”) is the quality that allows one interface to access a general class of actions. The specific action is determined by the exact nature of the situation.
  • A simple example of polymorphism is found in the steering wheel of an automobile. The steering wheel (i.e., the interface) is the same no matter what type of actual steering mechanism is used. That is, the steering wheel works the same whether your car has manual steering, power steering, or rack-andpinion steering. Therefore, once you know how to operate the steering wheel, you can drive any type of car.
  • The same principle can also apply to programming.

More generally, 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. Polymorphism helps reduce complexity by allowing the same interface to be used to specify a general class of action. It is the compiler’s job to select the specific action (i.e., method) as it applies to each situation. You, the programmer, don’t need to do this selection manually. You need only remember and utilize the general interface.

Types Of Polymorphism

There are mainly two types of Polymorphism -

  1. Compile Time, Or Static Polymorphism
  2. Run-Time, Or Dynamic Polymorphism.

1. Compile Time, Or Static Polymorphism -

We can find use of Compile Time, Or static  polymorphism in the Method Overloading.

Or in other words Method overloading is one of the ways that Java supports polymorphism.

Method overloading supports static polymorphism because it is one way that Java implements the “one interface, multiple methods” paradigm.

Example -

// Demonstrate method overloading.
class OverloadDemo {
void test() {
System.out.println("No parameters");
}
// Overload test for one integer parameter.
void test(int a) {
System.out.println("a: " + a);
}

// Overload test for two integer parameters.
void test(int a, int b) {
System.out.println("a and b: " + a + " " + b);
}
// overload test for a double parameter
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
}

class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
double result;
// call all versions of test()
ob.test();
ob.test(10);
ob.test(10, 20);
result = ob.test(123.25);
System.out.println("Result of ob.test(123.25): " + result);
}
}


 

Output -

No parameters
a: 10
a and b: 10 20
double a: 123.25
Result of ob.test(123.25): 15190.5625

 2. Run-Time, Or Dynamic Polymorphism

We can find use of RunTime, Or Dynamic  polymorphism in the Method Overriding.

Overridden methods allow Java to support run-time polymorphism. Polymorphism is essential to object-oriented programming for one reason: it allows a general class to specify methods that will be common to all of its derivatives, while allowing subclasses to define the specific implementation of some or all of those methods. Overridden methods are another way that Java implements the “one interface, multiple methods” aspect of polymorphism. Part of the key to successfully applying polymorphism is understanding that the superclasses and subclasses form a hierarchy that moves from lesser to greater specialization.

Dynamic, run-time polymorphism is one of the most powerful mechanisms that objectoriented design brings to bear on code reuse and robustness. The ability of existing code libraries to call methods on instances of new classes without recompiling while maintaining a clean abstract interface is a profoundly powerful tool.

Now we will understand it with an example -

Example -

package javaLearnings;

 

// Using run-time polymorphism.

class Figure {

   double dim1;

   double dim2;

   Figure(double a, double b) {

       dim1 = a;

       dim2 = b;

   }

   double area() {

       System.out.println("Area for Figure is undefined.");

       return 0;

   }

}

class Rectangle extends Figure {

   Rectangle(double a, double b) {

       super(a, b);

   }

   // override area for rectangle

   double area() {

       System.out.println("Inside Area for Rectangle.");

       return dim1 * dim2;

   }

}

class Triangle extends Figure {

   Triangle(double a, double b) {

       super(a, b);

   }

   // override area for right triangle

   double area() {

       System.out.println("Inside Area for Triangle.");

       return dim1 * dim2 / 2;

   }

}

public class Main {

   public static void main(String args[]) {

       Figure f = new Figure(20, 20);

       Rectangle r = new Rectangle(3, 6);

       Triangle t = new Triangle(5, 4);

       Figure figref;

       figref = r;

       System.out.println("Area is " + figref.area());

       figref = t;

       System.out.println("Area is " + figref.area());

       figref = f;

       System.out.println("Area is " + figref.area());

   }

}


 

Output -