Search code examples
javainheritanceoverridingoverloadingdynamic-dispatch

Java Overloaded & Overridden Function call


class A {
    void meth(A a) { System.out.println("A a.meth() called"); }
    void meth(D d) { System.out.println("A d.meth() called"); }
    void meth(E e) { System.out.println("A e.meth() called"); }
}

class D {}

class E extends D {}

class B extends A {
    void meth(A a) { System.out.println("B a.meth() called"); }
    void meth(B b) { System.out.println("B b.meth() called"); }
    void meth(D d) { System.out.println("B d.meth() called"); }
    void meth(E e) { System.out.println("B e.meth() called"); }
}


public class OverldOverd {
    public static void main (String[] args) {
        B b = new B();
        A a = b;

        a.meth(a);    // B a.meth() called
        a.meth(b);    // B a.meth() called /*! Why? !*/
    }
}

I'm trying to understand this line:

a.meth(b);

Here's my algorithm: a has static type A and dynamic type B, so we go down the hierarchy into class B. Also, the static type of the argument, ie. b, is B, thus it's output should have been instead:

B b.meth() called

Clearly i'm wrong. I'm trying to figure this out. Can somebody help me understand where i'm wrong? If my algorithm is wrong let me know. Thanks in advance.


Solution

  • Class A doesn't have meth(B a), so when you add this method to class B it doesn't override anything (not even meth(A a) from class A).

    When you compile a.meth(b) compiler picks method which fits B argument type the most. Since B extends A meth(A a) is picked.

    When you execute a.meth(b) polymoprhism (via dynamic binding) calls meth(A a) from actual type of object which a holds, which in your case is B. So you see B a.meth() called