What is the difference between dynamic and static polymorphism in Java?

Viewed 256026

Can anyone provide a simple example that explains the difference between Dynamic and Static polymorphism in Java?

14 Answers

Binding refers to the link between method call and method definition.

This picture clearly shows what is binding.

binding

In this picture, “a1.methodOne()” call is binding to corresponding methodOne() definition and “a1.methodTwo()” call is binding to corresponding methodTwo() definition.

For every method call there should be proper method definition. This is a rule in java. If compiler does not see the proper method definition for every method call, it throws error.

Now, come to static binding and dynamic binding in java.

Static Binding In Java :

Static binding is a binding which happens during compilation. It is also called early binding because binding happens before a program actually runs

.

Static binding can be demonstrated like in the below picture.

enter image description here

In this picture, ‘a1’ is a reference variable of type Class A pointing to object of class A. ‘a2’ is also reference variable of type class A but pointing to object of Class B.

During compilation, while binding, compiler does not check the type of object to which a particular reference variable is pointing. It just checks the type of reference variable through which a method is called and checks whether there exist a method definition for it in that type.

For example, for “a1.method()” method call in the above picture, compiler checks whether there exist method definition for method() in Class A. Because ‘a1′ is Class A type. Similarly, for “a2.method()” method call, it checks whether there exist method definition for method() in Class A. Because ‘a2′ is also Class A type. It does not check to which object, ‘a1’ and ‘a2’ are pointing. This type of binding is called static binding.

Dynamic Binding In Java :

Dynamic binding is a binding which happens during run time. It is also called late binding because binding happens when program actually is running.

During run time actual objects are used for binding. For example, for “a1.method()” call in the above picture, method() of actual object to which ‘a1’ is pointing will be called. For “a2.method()” call, method() of actual object to which ‘a2’ is pointing will be called. This type of binding is called dynamic binding.

The dynamic binding of above example can be demonstrated like below.

enter image description here

Reference static-binding-and-dynamic-binding-in-java

Static Polymorphism: is where the decision to resolve which method to accomplish, is determined during the compile time. Method Overloading could be an example of this.

Dynamic Polymorphism: is where the decision to choose which method to execute, is set during the run-time. Method Overriding could be an example of this.

Compile time polymorphism(Static Binding/Early Binding): In static polymorphism, if we call a method in our code then which definition of that method is to be called actually is resolved at compile time only.

(or)

At compile time, Java knows which method to invoke by checking the method signatures. So, this is called compile-time polymorphism or static binding.

Dynamic Polymorphism(Late Binding/ Runtime Polymorphism): At run time, Java waits until runtime to determine which object is actually being pointed to by the reference. Method resolution was taken at runtime, due to that we call as run time polymorphism.

Consider the code below:

public class X
{
    public void methodA() // Base class method
    {
        System.out.println ("hello, I'm methodA of class X");
    }
}

public class Y extends X
{
    public void methodA() // Derived Class method
    {
        System.out.println ("hello, I'm methodA of class Y");
    }
}
public class Z
{
public static void main (String args []) {

    //this takes input from the user during runtime
    System.out.println("Enter x or y");
    Scanner scanner = new Scanner(System.in);
    String value= scanner.nextLine();

    X obj1 = null;
    if(value.equals("x"))
        obj1 = new X(); // Reference and object X
    else if(value.equals("y"))
        obj2 = new Y(); // X reference but Y object
    else
        System.out.println("Invalid param value");

    obj1.methodA();
}
}

Now, looking at the code you can never tell which implementation of methodA() will be executed, Because it depends on what value the user gives during runtime. So, it is only decided during the runtime as to which method will be called. Hence, Runtime polymorphism.

Following on from Naresh's answer, dynamic polymorphism is only 'dynamic' in Java because of the presence of the virtual machine and its ability to interpret the code at run time rather than the code running natively.

In C++ it must be resolved at compile time if it is being compiled to a native binary using gcc, obviously; however, the runtime jump and thunk in the virtual table is still referred to as a 'lookup' or 'dynamic'. If C inherits B, and you declare B* b = new C(); b->method1();, b will be resolved by the compiler to point to a B object inside C (for a simple class inherits a class situation, the B object inside C and C will start at the same memory address so nothing is required to be done; it will be pointing at the vptr that they both use). If C inherits B and A, the virtual function table of the A object inside C entry for method1 will have a thunk which will offset the pointer to the start of the encapsulating C object and then pass it to the real A::method1() in the text segment which C has overridden. For C* c = new C(); c->method1(), c will be pointing to the outer C object already and the pointer will be passed to C::method1() in the text segment. Refer to: http://www.programmersought.com/article/2572545946/

In java, for B b = new C(); b.method1();, the virtual machine is able to dynamically check the type of the object paired with b and can pass the correct pointer and call the correct method. The extra step of the virtual machine eliminates the need for virtual function tables or the type being resolved at compile time, even when it could be known at compile time. It's just a different way of doing it which makes sense when a virtual machine is involved and code is only compiled to bytecode.

Related