public class A {
public static void main(String[] args) {
B b = new B();
A a = new B();
a.f();
A aaa = (A) b;
aaa.f();
}
public void f() {
System.out.println("I'm A");
}
}
class B extends A {
public void f() {
System.out.println("I'm B");
}
}
i ran this code, and get the result as below:
I'm B
I'm B
both a and aaa have a instance of B, so i think the result is reasonable.
however, i ran another code, like this:
public class Atest {
public static void main(String[] args) {
Atest a1 = new Atest();
Object a2 = new Atest();
System.out.println(a1.equals(a2));
System.out.println(a2.equals(a1));
System.out.println(a1.equals(new C()));
System.out.println(a2.equals(new C()));
}
public boolean equals(Object o) {
System.out.println("equals(Object o) is called!");
return true;
}
public boolean equals(Atest a) {
return true;
}
public boolean equals(C c) {
System.out.println("equals(C c) is called!");
return true;
}
}
class C {
}
and, i got the result
equals(Object o) is called!
true
equals(Object o) is called!
true
equals(C c) is called!
true
equals(Object o) is called!
true
i am confused that a2.equals(new C())
call the function public boolean equals(Object o)
a2 is an instance of Atest, i think a2.equals(new C())
should call the function public boolean equals(C c)
.
anybody can help me? really thanks!
a2 is an instance of Atest, i think a2.equals(new C()) should call the function public boolean equals(C c).
Although the value of a2
at execution time is a reference to an instance of Atest
, the compile-time type of a2
is just Object
. Overload resolution (i.e. choosing which method signature is called) is performed at compile time using the compile-time types; it's only the implementation of that signature that is resolved at execution time.
See more on this question at Stackoverflow