覆盖超类或子类中的equals和hashCode方法,或覆盖两者

时间:2011-12-12 16:44:41

标签: java equals hashcode

我对java编程比较陌生,并且在查找使用位置时遇到了问题 当我有一个继承自超类的子类时,equals和hashcode方法重写。

我想检查超类和子类的对象是否相等,并且想要知道超类和子类中的一个或两个是否需要它们的equals和hashcode方法覆盖?

我的子类没有实例变量,我的超类有2个实例变量(整数)

我的子类构造函数正在调用超类构造函数。

如果我想覆盖子类equals和hashcode方法是可能的,因为子类没有实例变量但是从其超类继承了2个实例变量?

4 个答案:

答案 0 :(得分:3)

这实际上提出了一个棘手的问题。假设你有一个类Foo,还有两个子类,FooA和FooB。在您的应用程序/域中是否有意义,因为FooA永远等于Foo或FooB?

如果是这样,你应该在超类中实现equals。并测试instanceof Foo。基本上,FooA或FooB中添加的任何额外字段都将被忽略。这通常是正确的。代码如下:

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;
}

如果没有,则需要在子类中实现equals。并且测试类是等于,而不仅仅是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;
}

总的来说,我认为大多数人都使用第一种方法。这似乎最适合你的问题。请参阅Josh Bloch的 Effective Java 。你会发现很多帖子,例如: Any reason to prefer getClass() over instanceof when generating .equals()?

答案 1 :(得分:0)

您需要为类覆盖它们,其对象将在equals()运行时检查或其对象将/可以在基于哈希的数据结构下

答案 2 :(得分:0)

由于子类中没有添加新属性,因此覆盖超类中的equals()hashcode()就可以了。在子类对象上调用这些方法时,将调用超类方法而不是类Object

中的方法。

但是,如果以后将新属性添加到子类中,则还需要在子类中重写这些方法。

答案 3 :(得分:0)

  

如果我想覆盖子类equals和hashcode方法就是这样   可能基于子类没有实例变量的事实   从其超类继承2个实例变量?

肯定是可能的,但它很少有意义。请注意,equals()的合同要求它是对称,即a.equals(b)b.equals(a)应始终具有相同的结果。当ab是以不同方式定义equals()的子类和超类的实例时,可能不会保留此合约。这意味着如果将两个类的实例放入集合中,则集合可能无法正常工作。