34
class A {
   boolean f(A a) { return true; }
}
class B extends A {
   boolean f(A a) { return false; } // override A.f(A)
   boolean f(B b) { return true; }  // overload A.f
}

void f() {  
   A a = new A();
   A ab = new B();
   B b = new B();
   ab.f(a); ab.f(ab); ab.f(b); //(1) false, false, *false*
   b.f(a); b.f(ab); b.f(b);    //(2) false, false, true
}

Can you please explain the first line last false output, why it is not true?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
nabil
  • 904
  • 3
  • 12
  • 28
  • I don't understand why people bother to post an answer that's so short and not so explanatory as @JonSkeet's post. – Luiggi Mendoza Jul 24 '12 at 06:16
  • I had a similar question some time back, maybe this helps you: http://stackoverflow.com/questions/3883414/is-there-any-reason-that-java-uses-late-static-binding-for-overloaded-methods-in – Korgen Jul 24 '12 at 06:16
  • 4
    increase your acceptence percentage please – developer Jul 24 '12 at 06:28

4 Answers4

59

can you please explain the first line last false output, why it is not true?

The compile-time type of ab is A, so the compiler - which is what performs overload resolution - determines that the only valid method signature is f(A a), so it calls that.

At execution time, that method signature is executed as B.f(A a) because B overrides it.

Always remember that the signature is chosen at compile time (overloading) but the implementation is chosen at execution time (overriding).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Well..because you are calling on type of A. So you can call only version of f(A a). that's returning false in B.

Ahmad
  • 2,110
  • 5
  • 26
  • 36
1

Since you are using the object type of A, you can call only f(A A). Because B overrides it.

LGAP
  • 2,365
  • 17
  • 50
  • 71
0

can you please explain the first line last false output, why it is not true?

Think otherwise :-

try commenting below in class B (the overriding code)

boolean f(A a) { return false; } // override A.f(A)

and add syso in Class A in this method --> boolean f(A a){....}

Then you'll see, ab.f(A a) or ab.f(B b) will invoke f(A a) method of class A only.

As ab is of type A.

Also please note - You'll not be able to call any method of class B as well from object ab.

Hope this further adds more clarification to above brilliant answers.

Lastly, you may seek this now --> Why do we assign a parent reference to the child object in Java?

Community
  • 1
  • 1
Vivek
  • 895
  • 11
  • 23