This technique ("getClass-based equals methods") does satisfy the equals
contract, but at great cost. The disadvantage of the getClass approach
is that it violates the "Liskov Substitution Principle," which states
(roughly speaking) that a method expecting a superclass instance must
behave properly when presented with a subclass instance. If a subclass
adds a few new methods, or trivially modifies behavior (e.g., by
emitting a trace upon each method invocation), programmers will be
surprised when subclass and superclass instances don't interact
properly. Objects that "ought to be equal" won't be, causing programs
to fail or behave erratically. The problem is exacerbated by the fact
that Java's collections are based on the equals method.