我正在阅读 Effective Java 中的等于合同,而在传递部分中我怀疑,在下面的代码中:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
现在我们有了这个
@Override
public boolean equals(Object o) {
if (!(o instanceof Point))
return false;
Point p = (Point)o;
return p.x == x && p.y == y;
}
public class ColorPoint extends Point {
private final Color color;
public ColorPoint(int x, int y, Color color) {
super(x, y);
this.color = color;
}
// Remainder omitted
}
// Broken - violates symmetry!
@Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint))
return false;
return super.equals(o) && ((ColorPoint) o).color == color;
}
ColorPoint cp = new ColorPoint(1, 2, Color.RED);
Point p = new Point(1, 2);
如果我运行p.equals(cp),它应该返回false,因为
return super.equals(o) && ((ColorPoint) o).color == color;
对两个类都无效,因为point
类不包含变量Color
为什么书中写的是真的?
答案 0 :(得分:2)
正如您在代码中看到的那样:
ColorPoint cp = new ColorPoint(1, 2, Color.RED);
Point p = new Point(1, 2); // create a Point
p.equals(cp) // call Point::equals
您调用Point::equals()
方法...但不比较颜色,请考虑 Point
没有颜色属性。
但无论如何,您可以使用ColorPoint::equals
cp.equals(p)
进行比较
ColorPoint cp = new ColorPoint(1, 2, Color.RED);
Point p = new Point(1, 2); // create a Point
System.out.println(p.equals(cp)); // call Point::equals
System.out.println(cp.equals(p)); // call ColorPoint::equals
将输出:
true
false
注意:小心!!!
此false
不适用于不同的color
属性,因为p
不是 instanceof ColorPoint
!!。
编辑:
嗯,当你在这种情况下有经验时更容易弄明白,但在开始时可能很难理解。在这种情况下,要遵循我调试的应用程序流程,但是您可以更轻松,更快速地添加打印语句。非常感谢,这对我来说很糟糕..我应该认为它是
:(
例如:
<强> ColorPoint::equals
强>
@Override
public boolean equals(Object o) {
System.out.println("equals ColorPoint");
if (!(o instanceof ColorPoint))
return false;
return super.equals(o) && ((ColorPoint) o).color == color;
}
<强> Point::equals
强>
@Override
public boolean equals(Object o) {
System.out.println("equals Point");
if (!(o instanceof Point))
return false;
Point p = (Point) o;
return p.x == x && p.y == y;
}
将输出相同的测试程序:
equals Point
true
equals ColorPoint
false
这为您提供了有关正在发生的事情的线索!