Runtime and Compile time Polymorphism in Java

Runtime and compile-time polymorphism are the two types of polymorphism that happens in java. Both of these polymorphism are named as per their working, we will see that later in this tutorial.

As discussed in previous tutorial, polymorphism is a mechanism in which an object or it's behavior can have many different forms. In java a class can have multiple methods with same name having different number/type of arguments, we call such methods as polymorphic method or behavior. This is also known as method overloading which is an example of compile time polymorphism.

Similarly in java, a child class can also have a method with same name having same number and type of argument as in parent class, this is known as method overriding in java which is an example of runtime polymorphism. We will understand method overloading and method overriding in detail in later tutorials.

What is Compile time Polymorphism or Static Binding

In compile time polymorphism, the call to a polymorphic behavior(method) is resolved at compile time rather than at runtime which means at runtime which particular form of that polymorphic method is going to be called get's resolved at compile time itself, that is why we call it compile time polymorphism.

In other words, in compile time polymorphism, the behavior of an object in a polymorphic method call get's decided at compile time itself rather than runtime. Let's understand this clearly with the program given below.

Compile time polymorphism program in Java

 class CompileTimePolymorphism {    
    void add(int a, int b) {
       int sum = a + b;
       System.out.println("sum of two numbers = "+sum);
     } 
     void add(int a, int b, int c) {
       int sum = a + b + c;
       System.out.println("sum of three numbers = "+sum);
     }
       
    public static void main(String [] args) {
      CompileTimePolymorphism obj = new CompileTimePolymorphism();       
      obj.add(20,30);
      obj.add(20,30,40);         
    }
 }

Output:

Sum of two numbers = 50 
Sum of three numbers = 90

Here add method is an overloaded or polymorphic method since it is more than once in class. This is known as method overloading in java. Here both methods differ on the basis of number of arguments they accept, first add method accepts two arguments while later accepts three arguments.

When compiler compiles the lines obj.add(20,30) and obj.add(20,30,40), at the same time it binds the call of add(int a, int b) with obj.add(20,30) and the call of add(int a, int b, int c) with obj.add(20,30,40). So it's the compiler who made the decision to call a particular form of polymorphic method at compile time itself. When the program runs, the binded method is called and prints it's result.

Since the decision of binding the particular form of polymorphic method is happening at compile time, that is why we call it compile time polymorphism. Compile time polymorphism is also known as static binding, static polymorphism, compile time binding or early binding.

Why do we call compile time polymophism as early binding ?

Since the binding of method that needs to be called is happening at compile time itself rather than at runtime, that is why we also call it as early binding.

What is Runtime polymorphism or Dynamic binding

In runtime time polymorphism, the call to a polymorphic method is resolved at runtime rather than compile time. It simply means which particular form of polymorphic method is going to be called get's resolved at run time rather than compile time, that is why we call it runtime polymorphism.

In other words, in runtime polymorphism, the behavior of an object in a polymorphic method call get's resolved at runtime rather than compile time. At runtime it's java virtual machine that decides which particular form of that polymorphic method is going to be called.

Runtime polymorphism can take place only when there is inheritance. In java child and parent classes can have method with same signature, when an object calls such methods, the compiler can't decide whether to call parent class method or child class method, it's jvm which makes the decision.

What is method signature ?

A method signature is part of the method declaration. It's the combination of the method name and the parameter list. Two methods will be called as of same signature if their names as well as number, type and order of their parameters are same.

Let's understand the runtime polymorphism with the program given below to make it more clear.

Runtime polymorphism program in Java

 class Person {
    void teach() {    
      System.out.println("I can teach ");
    } 
 }
 
 class Teacher extends Person {   
    void teach() {
      System.out.println("I teaches English");
    }    
    public static void main(String [] args) {
      Teacher teacher = new Teacher();  
      teacher.teach();
      Person person = new Teacher();  
      person.teach();    
    }
 }

Output:

I teaches English
I teaches English

Here the behavior teach is in both the classes, Person and Teacher. The teach method of person class is overridden in Teacher class. In java it is known as method overriding which is an example of runtime polymorphism.

Since the teach method is in both the classes with same signature, therefore the compiler is unable to bind the method calls with method definition while compiling the line teacher.teach() and person.teach(). So it's the jvm that needs to decide this at runtime.

At runtime the JVM decides which method is going to be called on the basis of actual type of object, and then executes that method. Since the binding of polymorphic method happens at runtime, we call this as runtime polymorphism. Runtime polymorphism is also known as Dynamic polymophism, Dynamic binding, Runtime binding or Late binding.

Why do we call runtime polymophism as Late binding ?

Since the binding of method that needs to be called is happening at runtime not at compile time, that is why we also call it as late binding.

What is dynamic method dispatch ?

Dynamic method dispatch is a mechanism by which a call to an overridden method is resolved at runtime. It is also referred as runtime polymorphism.

★★★
  • Constructor overloading is an example of compile time polymophism.
  • Method hiding is also an example of compile time polymorphism.
  • Java compiler differentiates multiple methods with same name on the basis of number of parameters or data type of parameters.