Ajay Yadav
Ajay Yadav

Reputation: 31

Run Time Polymorphism

class A {
    public void display(){
        System.out.println("From Class A");
    }
}

class B extends A {
    public void display() {
        System.out.println("From Class B");
    }
}

public class Test {
    public static void main(Strings[] args){

        A a = new A();
        A b = new B()
        a.display();
        b.display();
    }
}

Output:

From Class A    
From Class B

Now, I am getting the output as expected. But I want to know why I am using A b = new B(), when same thing I can achieve by using B b = new B().
What is the advantage of using former techniques, where and when it is beneficial for me?

Upvotes: 1

Views: 272

Answers (2)

Ahmad Khan
Ahmad Khan

Reputation: 2693

In your example, it doesn't matter which way you chose. Your example doesn't show the power of polymorphism.

Let's see a trivial example of Polymorphism:

enter image description here

interface Shape{
    void draw();
}

class Rectangle implements Shape{
    public void draw(){
        System.out.println("Drawing Rectangle.");
    }
}

class Triangle implements Shape{
    public void draw(){
        System.out.println("Drawing Triangle.");
    }
}

class Circle implements Shape{
    public void draw(){
        System.out.println("Drawing Circle.");
    }
}

Rectangle, Triangle, and Circle are just implementing their own definition of draw function.

Now, suppose you've to implement a drawAllShapes method in your Main class, which takes a bunch of shapes and print them all. But without polymorphism this can be hectic, as there can be different types of shapes. Now, here comes polymorphism to save us.

class RandomShapeFactory{
    public static Shape createRandomShape(){
        Shape randomShape;

        Random random = new Random();
        int randomNo = random.nextInt() % 3 + 1;
        if (randomNo == 1){
            randomShape = new Rectangle();
        }
        else if (randomNo == 2){
            randomShape = new Triangle();
        }
        else{
            randomShape = new Circle();
        }
        return randomShape;
    }
}

class Main{
    public static void main(String[] args){
        Shape[] shapes = new Shape[10];
        for (int i = 0; i < shapes.length; i++){
            shapes[i] = RandomShapeFactory.createRandomShape();
        }
        drawAllShapes(shapes);
    }

    public static void drawAllShapes(Shape[] shapes){
        for (int i = 0; i < shapes.length; i++){
            shapes[i].draw();
        }
    }
}

This implementation of drawAllShapes doesn't have to know whether the Shape at index i is a Circle or Triangle or what, whichever Shape it is, it just calls their implementation of the draw method.

main method has all random shapes, and when passed to the drawAllShapes method, their relative implementations are invoked.

This kind of implementation also follows the Open/Closed Principle, that if you want, in future, to add some more Shapes to the hierarchy, drawAllShapes method doesn't have to know about the new shapes either, just add new classes and implement the Shape interface, and drawAllShapes will work with those shapes too.

See the above example in action here.

Upvotes: 1

iM71
iM71

Reputation: 361

Lets take an example here. We all know birds can fly, but there are some exceptions. We know from their behavior, so lets model this.

Generally, birds can fly, so:

class Bird {
  void fly() {
      System.out.println("I can fly");
    }
 }

class Eagle extends Bird {
      void fly() {
        System.out.println("I can fly very high");
    }
}

We all know that ducks can't fly, but we don't say it for all birds. We say at runtime whether a specific bird can fly or not, depending on the bird.

class Duck extends Bird {
      void fly() {
        System.out.println("I can walk or swim only");
    }
}

class FlightDemo {
      public static void main(String[] args) {
         Bird bird = new Bird();
         bird.fly(); // output: I can fly

         Bird eagle = new Eagle();
         eagle.fly(); // output: I can fly very high

         Bird duck = new Duck();
         duck.fly(); // output: I can walk or swim only
      }
}

You saw that at runtime it's decided that ducks can't fly. You can override its fly behavior and it would walk or swim. We saw that Duck IS a Bird, and it can't fly, so we have overridden its behavior, and still Duck IS a Bird, and it can walk or swim.

Upvotes: 1

Related Questions