我的java程序中有这两个类:
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();
}
}
现在我的主要是做这两个简单的动作:
public static void main(String[] args) {
System.out.println(new A(5));
System.out.println(new B(5));
}
关于第一行,正如我预期的那样,它将创建一个A对象 - >转到A的toString
功能 - >获取True
函数的equals
,最后打印“5”。
关于B,我的预期和实际发生的事情是不同的......
我以为它会转到B的构造函数 - >转到构造函数并将数字5分配给x
- >返回B构造函数并将数字6分配给B的x
- >转到B的toString
方法并打印“B:”(直到这一点我是对的) - >转到A的toString
- >转到B的equals
,因为对象类型是B,这就是你关于方法激活的看法(*这是我错的地方) - >返回False
,因为B中的x
是6 - >打印数字5,因为我们在A toString
。
相反,在它调用A类toString
而不是转到B equals
方法的部分中,它停留在A中并激活A equals
...
我不知道为什么会发生这种情况,我所知道的是激活的方法是由对象类型决定的。
希望有人能在这里解释一下有什么不同......谢谢!
答案 0 :(得分:2)
为了扩展你的答案,为未来的读者:
在A.toString()
中,您拨打this.equals(five)
,其中five
的类型为A
。
在A的上下文中,匹配equals()
的唯一A
方法是A.equals(Object o)
。这就是JVM调用的方法。
如果有一个重写方法B.equals(Object o)
那么就会调用它。仅使用较窄类型的B.equals()
方法是不够的。
您可以通过提供A.equals(A a)
方法,或通过扩展B.equals()
的广度来获取Object
来获得您期望的行为。
几点说明:
equals()
,请接受Object
,这样您就会覆盖标准方法。答案 1 :(得分:0)
正如所给出的评论所解释的那样,我没有覆盖这个函数,我用该方法的全新签名重载了该函数。