Для реализации, основанной на наследовании, проверьте решение Tal Cohen, Как правильно выполнить метод equals ()?
Резюме:
В своей книге «Эффективное руководство по языку программирования Java» (Addison-Wesley, 2001) Джошуа Блох утверждает, что «просто невозможно расширить экземпляр класса и добавить аспект при сохранении равного контракта». Таль не согласен.
Его решение состоит в том, чтобы реализовать equals (), вызвав другой несимметричный blindlyEquals () в обоих направлениях. blindlyEquals () переопределяется подклассами, equals () наследуется и никогда не переопределяется.
Пример:
class Point {
private int x;
private int y;
protected boolean blindlyEquals(Object o) {
if (!(o instanceof Point))
return false;
Point p = (Point)o;
return (p.x == this.x && p.y == this.y);
}
public boolean equals(Object o) {
return (this.blindlyEquals(o) && o.blindlyEquals(this));
}
}
class ColorPoint extends Point {
private Color c;
protected boolean blindlyEquals(Object o) {
if (!(o instanceof ColorPoint))
return false;
ColorPoint cp = (ColorPoint)o;
return (super.blindlyEquals(cp) &&
cp.color == this.color);
}
}
Обратите внимание, что equals () должно работать через иерархии наследования, если Лисков должен быть выполнен Замена .