javainheritancepolymorphismsuperclassmethod-dispatch

Why target for dynamic dispatch is not determined at compile time?


I am now reading a Java book and stuck for quite a while now thinking about how Dynamic Method Dispatch works. I understand that it's a powerful and valuable feature but I don't understand its main principle. For example, I have a class B which inherits from class A and overrides some of A's methods. So, when I write a program, I may use these expressions

A a = new B();
a.someOverridenMethod();

I know that in this situation the version B of method will be called, not A. But the part that I don't understand is, why can't the compiler determine which version (superclass or some subclass) of the method to call? I mean, it's explicitly stated that the variable a will hold a reference to object of type B. So why is it only possible to determine this at runtime even though it's explicitly stated in the code?


Solution

  • You totally misunderstood the run-time thing.

    It means that class A can hold reference of any of it's subclasses which will be determined at runtime. Their maybe other statement like a =new C(); after A a = new B(); and since their can be many statements like this therefore it's said the the version of the method will be determined at run-time

    i.e. a will be holding reference of B and maybe at some other moment it will be holding the reference of C where both B and C are sub classes of A

    Here's an example:

     class A {
    
    void override()
    {
        System.out.println("Inside A");
    }
    
    }
    
     class B extends A
    {
         void override()
         {
            System.out.println("Inside B");
         }  
    
    }
    
     class C extends A
     {
         void override()
         {
             System.out.println("Inside C");
         }
     }
    
     class Main
     {
         public static void main(String args[])
         {
             A a =new A();
    
             a.override();
             a=new B();
    
             a.override();
    
             a=new C();
    
             a.override();
         }
     }
    

    Output:

    Inside A
    Inside B
    Inside C
    

    Hope this clears your doubt.