The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

Polymorphism in Java

Overview
Polymorphism is the ability of a message to be processed in more than one way. We have already seen how method overloading achieves static polymorphism and method overriding accomplishes dynamic or runtime polymorphism. Static polymorphism is also known as early binding ( call to an overloaded method is resolved at compile time depending on the argument list ) and dynamic polymorphism is also known as late binding ( call to an overridden method is resolved at run time depending on the object which is invoking it ). In this section, we will elaborate more on runtime polymorphism.

Runtime Polymorphism
Suppose, we are designing a utility to draw different types of shapes ( rectangle, circle, triangle, etc ). The shape to be drawn is known at runtime. The basic approach to the problem is to design a class called Shape with a method called draw( ) and then extend it for different shapes. For e.g, a subclass Rectangle to draw a rectangle, a subclass Circle to draw a circle and so on. Every subclass define their own draw( ) method. Now, we will use a reference variable of Shape class to refer to the objects of child classes ( Rectangle, Circle, etc. ). At runtime, appropriate draw( ) method is called depending on the object to which the reference variable is currently referring. Thus a common reference variable of parent class refers to different child classes at different point of program execution. In this way, we have achieved run time polymorphism. Also, the Shape class can be seen as a level of abstraction on top of subclasses ( Rectangle, Circle, etc. ). This is known as abstraction at the design level. An external class simply specifies the shape type and calls the draw( ) method of Shape class. Actual draw( ) method is resolved depending on shape type at run-time. Let's look at the sample implementation of the problem.

class Shape {
   void draw() { // default implementation of draw method
      System.out.println("Drawing a shape");
   }
}

class Rectangle extends Shape { // Rectangle is-a Shape
   /* Override the draw method
    * Implementation for drawing a rectangle
    */
   void draw() {
      System.out.println("Drawing a Rectangle");
   }
}

class Circle extends Shape { // Circle is-a Shape
   /* Override the draw method
    * Implementation for drawing a circle
    */
   void draw() {
      System.out.println("Drawing a Circle");
   }
}

public class PolymorphismDemo {
   public static void main(String args[]) {
      Shape s = new Rectangle(); /* 's' is a reference variable of Shape
                                  * class which refers to Rectangle object */
      s.draw(); // calls draw() method of Rectangle class
      s = new Circle(); // 's' refers to a circle object now
      s.draw(); // calls draw() method of Circle class
   }
}

When a reference variable of parent class refers to an object of child class, it is known as upcasting. The above program is an example of hierarchical inheritance. Following program shows how run time polymorphism is achieved in case of multi-level inheritance.

class Vechile {
   void vechileInfo() {
      System.out.println("Vechile");
   }
}

class Car extends Vechile {
   void vechileInfo() {
      System.out.println("Car is a Vechile");
   }
}

class Ferrari extends Car {
   void vechileInfo() {
      System.out.println("Ferrari is a Car");
   }
}

public class PolymorphismMultilevelDemo {
   public static void main(String args[]) {
      Vechile v1 = new Vechile();
      Vechile v2 = new Car(); // 'v2' refers to Car object
      Vechile v3 = new Ferrari(); // 'v3' refers to Ferrari object
      v1.vechileInfo(); // calls method of Vechile class
      v2.vechileInfo(); // calls method of Car class
      v3.vechileInfo(); // calls method of Ferrari class
   }
}

Back | Next