two distinct scenarios:
? If subclasses can have their own notion of equality, then the symmetry requirement forces you to use the getClass test.
? If the notion of equality is fixed in the superclass, then you can use the instanceof test and allow objects of different subclasses to be equal to one another.
For example:
? In the example with employees and managers, we consider two objects to be equal when they have matching fields. If we have two Manager objects with the same name, salary, and hire date, but with different bonuses, we want them to be different. Therefore, we used the getClass test.
? But suppose we used an employee ID for equality testing. This notion of equality makes sense for all subclasses. Then we could use the instanceof test, and we should have declared Employee.equals as final.
Here is a recipe for writing the perfect equals method:
1. Name the explicit parameter otherObject—later, you will need to cast it to another variable that you should call other.
2. Test whether this happens to be identical to otherObject:
if (this == otherObject) return true;
This statement is just an optimization. In practice, this is a common case. It is much cheaper to check for identity than to compare the fields.
3. Test whether otherObject is null and return false if it is. This test is required.
if (otherObject == null) return false;
4. Compare the classes of this and otherObject. If the semantics of equals can change in subclasses, use the getClass test:
if (getClass() != otherObject.getClass()) return false;
If the same semantics holds for all subclasses, you can use an instanceof test:
if (!(otherObject instanceof ClassName)) return false;
5. Cast otherObject to a variable of your class type:
ClassName other = (ClassName) otherObject
6. Now compare the fields, as required by your notion of equality. Use == for primitive type fields, Objects.equals for object fields. Return true if all fields match, false otherwise.
return field1 == other.field1 && Objects.equals(field2, other.field2) && . . .;
If you redefine equals in a subclass, include a call to super.equals(other).