Polymorphism in Java

Polymorphism in Java

Another very useful property of OOPs is Polymorphism. Today we will try to get familiar with it. What does Polymorphism mean in very general case? It’s just occurrence in different forms. It has similar meaning. When we were using constructor, a type of polymorphism was being used. Like see this code:

public class Inheritance {
    public static void main(String[] args) {

    }
    static class Parent{
        double English;
        double Mathematics;
        double History;
        Parent(String name){
            System.out.println("Student name is "+name);
        }
        Parent(double English,double Mathematics, double History){
            this.Mathematics=Mathematics;
            this.English=English;
            this.History=History;
        }
    }
}

In this code we are using same constructor but with different arguments. So when we want to use first constructor we will enter one argument while for using another we will give 3 inputs. This is a type of Polymorphism.

Compile-time/Static Polymorphism

This is a very simple type of Polymorphism. When return type, number of arguments, type of arguments and order of type of arguments differ, we can use method with same name, like constructor in above case. This is known as Method Overloading. Now the question is: Why this is known as Compile-time Polymorphism? Because which method is to be called is decided at Compile time. A very good example for understanding this is when try to enter 4 arguments in above Parent constructor, it will show error, that means it is not being able to compiled!

Run-time/Dynamic Polymorphism

Previous type of Polymorphism was used many a times by us and is very easy to understand but this type is that which creates a lot of confusion. Ask yourself, what will happen if method has same return type, same number and type of arguments, means compiler could not make difference between those? Of course, you can’t do this in one same class but you can do this in inherited classes! Doing this is called Overriding a Method. Let’s see how it works.

public class Inheritance {

    public static void main(String[] args) {
}

    static class shapes{

        void message(){

            System.out.println("I am in shapes!");

        }

    }

    static class circle extends shapes{

        void message(){

            System.out.println("I am in circle!");

        }

    }

    static class square extends shapes{

        void message(){

            System.out.println("I am in square!");

        }

    }

}

Here we created three classes shapes, circle and square where circle and square are children of shapes. We also created a method message which is differing only in body. It’s return type is void and taking 0 arguments. This is called Method Overriding. Now let’s play with objects to deeply understand this!

public class Inheritance {

    public static void main(String[] args) {

    shapes universe=new shapes();

    circle shape1=new circle();

    shapes parlleluniverse=new circle();

    universe.message();

    shape1.message();

    parlleluniverse.message();

    }

    static class shapes{

        void message(){

            System.out.println("I am in shapes!");

        }

    }

    static class circle extends shapes{

        void message(){

            System.out.println("I am in circle!");

        }

    }

    static class square extends shapes{

        void message(){

            System.out.println("I am in square!");

        }

    }

}

The output is:

I am in shapes!

I am in circle!

I am in circle!

Here first two cases are very simple, but the interesting one is the third one. The object belongs to shapes class but is of type circle class. How this is being executed? Actually, here comes the run-time polymorphism. Just read this line very carefully

What function to be accessed is decided by left and which specific function to be accessed is decided by right.

What does this mean? Object belongs to Shapes class hence compiler will allow you to access all the properties of this class, which again means if you will remove message from shapes class, you will not be able to access even though message is present in circle class. Think if you are the compiler, you will first see that if message() is present in shapes class but in current case it's not! hence it will not compiled. Now if it is present then the type of message to be executed will be decided at run-time not at compile time and hence will be decided by type of object, which is circle here. Hence gives the above output!