在java

时间:2016-08-03 10:26:00

标签: java casting

我有以下代码

@Override
public boolean equals(Object o) {
    if (!(o instanceof ColorPoint))
        return false;
    return super.equals(o) && ((ColorPoint) o).color == color;
}

我有以下

Point p = new Point(1, 2);
ColorPoint cp = new ColorPoint(1, 2, Color.RED);

ColorPoint继承Point。问题是当我p.equals(cp)为什么返回true时?我的意思是在最后一次回归时它会调用super.equal但是在那个演员身上会发生什么?它在使用ColorPoint

的演员表中返回的内容
@Override public boolean equals(Object o) {
if (!(o instanceof Point))
return false;
Point p = (Point)o;
return p.x == x && p.y == y;
}

这与Point类相同

4 个答案:

答案 0 :(得分:3)

您使用equals的{​​{1}}方法,而不是Point的方法。

更改为ColorPoint,您将获得cp.equals(p)

请注意,您不应以可能使其不对称的方式实现false。如果要匹配类,请务必检查是否要扩展类:

equals

答案 1 :(得分:1)

除了其他答案之外,equals()的实现违反了JavaDocs中定义的合同:

  

equals方法在非null对象引用上实现等价关系:
   

  • ...
  •    
  • 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。    
  • ...

这意味着您不应检查o instanceof Point,而是o.getClass() == getClass()。通过实施,您在调用p.equals(cp)cp.equals(p)时会得到不同的结果,从而违反了该合同。这可能会导致细微的错误,因为大多数收藏都依赖于合同。

答案 2 :(得分:0)

equals已为ColorPoint实施equals方法。你在Point上调用false。它只会检查两个坐标 - 而不是颜色。

如果致电cp.equals(p);

,您将获得if

答案 3 :(得分:0)

类层次结构和equals()不能很好地结合在一起。

如果使用equals()在超类中实现instanceof(以便子类可以等于超类),则可以通过对称打破equals()的要求:

p.equals(cp) // true
cp.equals(p) // false

如果使用getClass().equals(other.getClass())实现它,您将获得正确的合同,但阻止任何子类实例与您的实例相同 - 这可能是一个问题,例如当使用像Hibernate这样的ORM为你的类创建代理类时。

equals()似乎在多个类中运行良好的唯一情况是,当您有一个接口并根据该接口的方法定义equals()合同时,那么编写所有实现,以便他们遵守合同并仅使用接口公开的信息。例如,可以在java.util.List及其常见实现中看到这一点。