Search code examples
javainheritancepolymorphismoverridingdynamic-binding

Java-dynamic-binding-problem-understanding


So, I have this problem (which I am guessing has something to do with dynamic binding) that I can not wrap my head around.

class A {
    public int m(A p) {
        return 12;
    }

    public int n(A p) {
        return 38;
    }
}
class B extends A {
    public int m(B p) {
        return 3;
    }

    public int n(A p) {
        return 7;
    }
}

class C extends A {
    public int m(A p) {
        return 38;
    }
    public int n(A p) {
        return 4;
    }
}
class D extends A {
    public int m(A p) {
        return 1;
    }

    public int n(D p) {
        return 2;
    }
}
class Main {
    public static void main(String argv[]) {
        A x = new C();
        A y = new D();
        D z = new D();
        System.out.println(x.m(z) + y.n(z)); //*
    }
}

The commented line is where I get stuck. Why the result is 76? what does it depend on, because I have been searching all over the internet and I wasn't able to find an example for it. if you can come up with little explanations I would very much appreciate.


Solution

  • It returns 76, because both parts of sum returned 38:

    x.m(z) this part means, try to find method m within class A (because x is A) which can accept D, there is no such method in A, but there is m which accepts A, as soon as D extends from A - this method is used, so we're calling method A.m(A), but this method is overridden in C, so overridden method is actually executed, ie C.m(A)

    y.n(z) this part follows the same logic and tries to call A.n(A), but class D does not override method n - public int n(D p) is not override for A.n(A), so non overridden method from A is executed

    I suggest you to always use @Override annotation to allow compiler to validate what methods are actually overridden and what not, here is annotated version which is easier to follow:

    class A {
        public int m(A p) {return 12;}
        public int n(A p) {return 38;}
    }
    class B extends A {
        public int m(B p) {return 3;}
        @Override
        public int n(A p) {return 7;}
    }
    class C extends A {
        @Override
        public int m(A p) {return 38;}
        @Override
        public int n(A p) {return 4;}
    }
    class D extends A {
        @Override
        public int m(A p) {return 1;}
        public int n(D p) {return 2;}
    }
    class Main {
        public static void main(String argv[]) {
            A x = new C();
            A y = new D();
            D z = new D();
            System.out.println(x.m(z) + y.n(z)); //*
        }
    }
    

    to allow compiler to find n(D) method you must cast y to D, like ((D)y).n(z) or use derived type in declaration D y = new D();