class A{
void m1(A a) {System.out.print("A");}
}
class B extends A{
void m1(B b) {System.out.print("B");}
}
class C extends B{
void m1(C c) {System.out.print("C");}
}
public class d {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C();c1.m1(c2);
}}
Output of this code is 'A'.
But if I modify class A as:
class A{
void m1(C a) {System.out.print("A");}
}
then the output is 'C'. Could somebody please explain how is this code working?
(You’ve made this more confusing than it needs to be by using the same inheritance hierarchy for both the parameter types and the implementation. Separating those would probably help to simplify it in your mind.)
The type of
c1isA. Therefore when working out which method signature it’s going to call, the compiler can only look at methods declared inA.So in the first case, the compiler is going to call
m1(A); in the second case, the compiler is going to callm1(C).Now in the first case, the
m1(A)method is never overridden, so actually the execution-time type ofc1is irrelevant.In the second case,
m1(C)is overridden byC, so the implementation inCis called because the execution-time type ofc1isC.So remember: