Question

my question may not been very clear. looking through this example, I can explain further. As I reading the answers posted for this Static vs Dynamic Binding Logic , I got this question.

There are two version of code, both of which are exactly the same, except for change in parameter type for Class B p (double i)

version 1:

    import java.lang.*;

    public class X
    {
        public static void main(String [] args) 
        { 
            B c = new A(); 

            c.p(10);   
            c.p("AAA");
            ((A)c).p(10);
        } 
    } 
        class B { 
            public void p(String s) 
            { 
                System.out.println("B: my string is " + s); 
            } 

           public void p(int i) 
            { 
                System.out.println("B: twice my double is: " + i*2); 
            } 
        }

        class A  extends B{ 
            public void p(int i) 
            { 
                System.out.println("A: my number is " + i); 
            } 
        } 

    Here the output is :
    A:my number is 10
    B: my string is AAA
    A: my number is 10

version 2:

    import java.lang.*;
    public class X
    {
        public static void main(String [] args) 
        { 
            B c = new A(); 
        c.p(10);  
        c.p("AAA");
        ((A)c).p(10);
    } 
} 
    class B { 
        public void p(String s) 
        { 
            System.out.println("B: my string is " + s); 
        } 

       public void p(double i) 
        { 
            System.out.println("B: twice my double is: " + i*2); 
        } 
    }

    class A  extends B{ 
        public void p(int i) 
        { 
            System.out.println("A: my number is " + i); 
        } 
    } 

    Here the output is :
        B:twice my double is 20.0
        B: my string is AAA
        A: my number is 10

my question is as follows: why the p(int) from Class A is called in the first version while p(double) from Class B is called in the second version.

version 1:
methods of A
A -----> p(string), p(int)- this is overridden from Class B
method of B
B ------> p(string), p(int)

version 2:
methods of A
A -----> p(string), p(double), p(int) No more overriding
method of B
B ------> p(string), p(double)

when I declare B c;, I initialize the reference variable which is of type B

next I assign c to the new object, by c = new A();

hence this declaration B c = new A(); creates an instance of class A and assigns to the variable of type B. now whenever the methods calls are executed on c, the compiler first checks if the methods exists in B (since it is of B type), but the actual method that is called is of the object (which is an A instance). why this behavior is not seen in the above example? or if my reasoning is wrong, kindly correct me.

Thanks

Was it helpful?

Solution

In the first version you override a method and in the second method you overload it.

In the first version you have p in both class A and class B. When you call c.p(...) the compiler uses the static type of c to create the call. On run time the code uses the class`s virtual table (read about it if you're not familiar) in order to find the correct polymorphic method.

In the second version the compiler does the cast from int to double for you on compile time and then on run-time it again uses the virtual table of A to find a method with signature p(double) (because it casted the int on compile-time for static-type compliance). The virtual table points to the method in B because A doesn't override it.

You can further read about it in the book "Effective Java" - Item 41, Page 191:

selection among overloaded methods is static, while selection among overridden methods is dynamic

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top