Call super.equals and super.hashCode in a child class?

If I implement equals() and hashCode() both the parent and child classes, it is necessary to call super.equals() on equals() in the child class, for example.

 public boolean equals(Object obj) { if (obj.getClass() != ChildClass.class) { return false; } return super.equals() && this.var == ((ChildClass) obj).var; } 
+7
source share
3 answers

No, this is not necessary, and probably would be wrong. Indeed, part of the reason you override equal is that super.equals doesn't give the correct behavior (right?).

Or else, if super.equals gives the correct behavior, you probably don't need to worry about overriding it.

But if you override equals , then yes, you also need to override hashCode .

+8
source

If your superclass does not implement equals, then calling super.equals will give you an Object implementation that compares only references, so in any normal equivalent implementation where you want to compare a business key, this will actually cause a lot of false negatives.

However, your implementation above is really no different from the semantic than the standard default implementation is Object, since you just use == for comparison.

As with hashCode, if you override equals, you really have to override hashCode to save the contract of the two. For example, if you use the business key for peers, you probably should use the same business key for the hash code so that two identical objects generate the same hash code.

+2
source

EDIT

I just noticed that you used class equality, not instanceof - this means that reflexivity will be correct. In your example, using super.equals is probably correct if the superclass does not contain an equality definition that contradicts what your subclass requires (e.g. Object ).

The main thing is that the definition of equality should come from only one type (class or interface) in your class hierarchy. If super.equals used in the implementation of this definition, that’s fine.

END EDIT , source code below

This is almost certainly wrong, because it violates the reflective property of equality.

Say you have a Shape, and it is equal to another Shape if they are of the same type: Square is Square, Circle is Circle, etc. Now you extend this to make ColoredSquare, which adds color checking.

 Shape shape1 = new Shape(SQUARE); Shape shape2 = new ColoredShape(SQUARE, RED); 

You implement ColoredSquare.equals as super.equals(other) && other.color == this.color , as in your question. But note that shape1.equals(shape2) == true (since shape1 just uses Shape.equals ), but shape2.equals(shape1) == false (since it adds color checking).

The moral of the story is that using this kind of cascading equality is really difficult, if not impossible. Basically, equality should come only from one type within your type hierarchy - be it Object , the type itself, supertype or some interface that defines the contract (for example, in the structure of collections that define equality for Set , List , etc. .).

0
source

All Articles