Explanation
BTW A
doesn't have any equals
methods at all.
But you do
ab.equals(a1)
ab.equals(b1)
And ab
is:
A ab = new B();
So while it is actually a B
, the variable is of type A
.
Javas rules for choosing methods in such situations will start looking for an equals
method in the A
class. And it actually has one, the default implementation inherited from Object
. It has the signature
public boolean equals(Object other)
So it decides for this signature. Now it asks the actual instance behind ab
, which is of type B
, for a method with that signature. It chooses the overriden implementation in B
:
public boolean equals(Object other) {
System.out.print("Object");
}
And consequentially prints Object
in both cases.
Details
The details for this are defined in JLS§15.12. Method Invocation Expressions. It talks about finding the most specific match. The rules can get quite complex if you dive deep into it.
Some excerpts:
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to search for definitions of methods of that name.
The second step searches the type determined in the previous step for member methods. This step uses the name of the method and the argument expressions to locate methods that are both accessible and applicable, that is, declarations that can be correctly invoked on the given arguments.
There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is the one used at run time to perform the method dispatch.
The class or interface determined by compile-time step 1 (§15.12.1) is searched for all member methods that are potentially applicable to this method invocation; members inherited from superclasses and superinterfaces are included in this search.
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.