这个equals()方法如何返回true?

时间:2016-06-06 09:37:17

标签: java equals

我正在阅读 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

为什么书中写的是真的?

1 个答案:

答案 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

这为您提供了有关正在发生的事情的线索!