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
  • 386,424
  • 207
  • 554
  • 861
nabil
  • 884
  • 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

60

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,335,956
  • 823
  • 8,931
  • 9,049
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,040
  • 4
  • 23
  • 33
1

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

LGAP
  • 2,245
  • 16
  • 49
  • 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
  • 865
  • 10
  • 21