我有这两个类:
public class A {
private final static A five = new A(5);
public final int x;
public A(int x) {
this.x = x;
}
public boolean equals(Object o) {
return x == ((A) o).x;
}
public String toString() {
return equals(five) ? "five" : (x + "");
}
}
public class B extends A {
public final int x;
public B(int x) {
super(x);
this.x = x + 1;
}
public boolean equals(A o) {
return x == o.x;
}
public String toString() {
return "B: " + super.toString();
}
}
这是我main
计划中的两行:
System.out.println(new B(5));
System.out.println((new B(5)).equals(new A(5)));
我知道在Java中调用的方法是由Object类型决定的,
在两个行中,对象的类型为B
,因此在第一行中我调用B
类toString()
方法,
从那里开始打印" B:"它调用A
类toString()
,现在它尝试激活equals()
方法。
根据我对Java中多态性的理解,对象类型仍然是B
,所以它会尝试激活B
的{{1}}方法,但实际上在调试它时会激活{{ 1}}类equals()
,这是我不了解的第一件事。
稍后在我的A
程序的第二行,我正在初始化equals()
对象,并调用main
方法,所以在我看到了第一行代码表现得很好,我会打电话给B
equals()
,但实际上这一行会转到A
' s equals()
。 ..
我有点困惑,首先我的B
程序的2行与我所了解的多态代码的工作方式不同,2行的行为不同,尽管它们的行为应该相同......
希望你能告诉我这段代码是如何工作的以及原因。
答案 0 :(得分:2)
B中的equals()方法不会覆盖A中的equals()方法。一个将Object作为参数,另一个将A作为参数。
编译A.toString()时,编译器会在A及其所有名为equals()的超类中查找一个方法,并将其任何超类/接口的A作为参数。唯一存在的是A.equals(Object)。这就是toString()使用的内容。
多态性允许在运行时根据调用方法的对象类型选择适当的方法。不是关于方法的参数类型。如果方法重载(即存在多个具有相同名称但不同参数类型的方法),则在编译时选择使用哪种方法静态。