Joshua Blotch 的Effective Java指出:
equals
除非您愿意放弃面向对象抽象的好处,否则无法在保留契约的同时扩展可实例化类并添加值组件。
Effective Java给出了一些破坏对称性、传递性或Liskov 替换原则的示例。我想你已经阅读了该项目。我认为我不应该在这里发布整个项目。但是我找到了一个遵守合同的解决方案:
Point
:_
public class Point{
private final int x;
private final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
protected boolean equalsImpl(Point p){
return p.x == x && p.y == y;
}
@Override
public final boolean equals(Object o) {
if(!(o instanceof Point))
return false;
Point p = (Point)o;
return equalsImpl(p) && p.equalsImpl(this);
}
// Remainder omitted ...
}
ColorPoint
:_
public class ColorPoint extends Point{
private java.awt.Color color;
public ColorPoint(int x, int y, java.awt.Color color){
super(x, y);
this.color = color;
}
@Override
protected boolean equalsImpl(Point p){
return (p instanceof ColorPoint) &&
super.equalsImpl(p) &&
((ColorPoint)p).color == color;
}
// Remainder omitted ...
}
我知道在这种情况下应该使用组合,但我想知道我的解决方案是否真的遵守equals
合同。如果是的话,Effective Java声明的错误是什么?