1
votes

I am relatively new to java programming and have had a problem finding out where to use equals and hashcode method overriding when I have a subclass inheriting from the superclass.

I want to check for equality for objects of the superclass and subclass and was wanting to know if either or both the superclass and subclass would need their equals and hashcode methods overriding?

My subclass has no instance variables and my superclass has 2 instance variables (integers)

My subclass constructor is calling the superclass constructor.

If I want to override the subclass equals and hashcode methods is that possible based on the fact the subclass has no instance variables but inherits the 2 instance variables from its superclass?

4

4 Answers

4
votes

This actually brings up a difficult question. Let's say you have a class Foo, and two subclasses, FooA and FooB. Does it make sense, in your application/domain, for a FooA to ever be equals to a Foo or a FooB?

If so, you should implement equals in the superclass. And test for instanceof Foo. Basically, any extra fields that are added in FooA or FooB will get ignored. Often this is proper. Code looks like:

public boolean equals(Object o) {  // perfectionists will make this final
  if (this == o)
     return true;
  if (o instanceof Foo) {  // note that Foo, FooA and FooB would all pass
     Foo oFoo = (Foo)o;
     // compare all the fields of Foo here
  }

  return false;
}

If not, you need to implement equals in the subclasses. And test for the classes be equals, not just instanceof. e.g.

public boolean equals(Object o) {
  if (this == o)
     return true;
  if (o == null)  // this extra check is needed to avoid a NPE
    return false;
  if (o.getClass() == this.getClass()) {  // must be an exact match
     FooA oFoo = (FooA)o;
     // compare all the fields here
  }

  return false;
}

In general, I think most people use the first approach. And it seems most appropriate to your problem. See Effective Java by Josh Bloch. You'll find a lot of posts on this, e.g. Any reason to prefer getClass() over instanceof when generating .equals()?

1
votes

Since there are no new attributes added in the subclass, overriding equals() and hashcode() in the superclass will be fine. When you call these method on subclass objects, the superclasses methods will be called not those from class Object

However, if at a later date new attributes are added to the subclass, you will need to override those methods in the subclass also.

0
votes

You need to override them for the class, Whose object would be under equals() check at runtime or whose Object would/can be under Hashing based Data Structure

0
votes

If I want to override the subclass equals and hashcode methods is that possible based on the fact the subclass has no instance variables but inherits the 2 instance variables from its superclass?

It's certainly possible, but it rarely makes sense. Note that the contract of equals() requires it to be symmetric, i.e. a.equals(b) and b.equals(a) should always have the same result. When a and b are instances of a sub- and superclass that define equals() differently, this contract is probably not kept. That means if you put instances of the two classes into a collection, the collection may not work correctly.