The conclusion of the Java fragment did not understand, probably due to polymorphism

I was wondering why this Java bit gives 2, not 3:

public class Test { private static class A { int f(A a) { return 1; } } private static class B extends A { int f(A a) { return 2; } int f(B b) { return 3; } } public static void main(String[] astrArgs) { A ab = new B(); B b = new B(); System.out.println( ab.f(b) ); } } 

I came across this in a test question and could not get the logic.

+4
source share
2 answers

The compile time type ab is just A Therefore, when the compiler sees this expression:

 ab.f(b) 

... it only considers method signatures declared on A and its superclasses (just Object in this case).

So, the compiler decides to call a method with signature f(A a) .

Now, at runtime, the VM chooses which implementation of this signature to execute based on the runtime type of the method invocation target, which is B

B overrides f(A a) , so the implementation override is called - and returns 2.

Basically, at compile time, an overload is determined to determine which method signature to call based on the compilation time types of both the invocation target and the arguments, and the redefinition is determined at runtime to develop an exact implementation to execute based on the runtime type of the target.

+8
source

In this case, ab is of type A, but an instance of B is created. Only the method is known.

 int f(A a) { return 1; } 

b is of type A, therefore it is valid. B overrides int f (A a), so this method is used.

 int f(A a) { return 2; } 

Hope this helps.

0
source

All Articles