dhulmul
dhulmul

Reputation: 750

Method overloading/overriding in Java subclass object with superclass reference variable

 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?

Upvotes: 3

Views: 5713

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1503944

(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 c1 is A. Therefore when working out which method signature it's going to call, the compiler can only look at methods declared in A.

So in the first case, the compiler is going to call m1(A); in the second case, the compiler is going to call m1(C).

Now in the first case, the m1(A) method is never overridden, so actually the execution-time type of c1 is irrelevant.

In the second case, m1(C) is overridden by C, so the implementation in C is called because the execution-time type of c1 is C.

So remember:

  • Overload resolution (which method signature is called) is determined at compile-time, based on the compile-time types of both the method target and the argument expressions
  • The implementation of that method signature (overriding) is based on the actual type of the target object at execution time.

Upvotes: 10

Related Questions