How Joshua Bloch writes there is no general solution when you try to create subclass adding fields that changes the state of entity.
The solution with canEqual looks like a workaround.
In OOP the problem could be solved by separating interface and implementation. Very strange that no one wrote this before, or did I miss something?
interface Point {
int getX();
int getY();
}
interface ColoredPoint extends Point {
Color getColor();
}
// lombok annotations
@Getter
@AllArgsConstructor
// compare by own fields x, y
@EqualsAndHashCode(of = {"x", "y"})
class PointImpl implements Point {
private final int x;
privaet final int y;
}
@Getter
@AllArgsConstructor
// compare by own fields point, color
@EqualsAndHashCode(of = {"point", "color"})
class ColoredPointImpl implements ColoredPoint {
private final Point point; // just delegate getX, getY to point
private final Color color;
}
in that way the equality and Liskov principle could be satisfied.