覆盖超类的equals和hashcode方法。我是否为子类做

时间:2011-12-13 00:32:20

标签: java hash equals

我有一个包含2个实例变量的超类(比如int aint b)和 现在已经决定我需要在我的子类int c中有一个实例变量。

我已经覆盖了要考虑的超类equals和hashCode方法 对象/值的相等性。我还覆盖了超类toString来给出一个字符串 表示对象的状态(变量值)。

基于以上和事实,我现在在我的子类中有一个实例变量int c 我想知道我是否

  1. 需要覆盖子类中的toString方法,或者这是不是没有,因为我在超类中有一个可用于子类字符串表示的有效的可继承toString方法(已经覆盖)?
  2. 需要覆盖子类中的equals方法。可以做到这一点 通过调用超类equals方法并在调用后为我的子类实例变量添加比较代码,还是需要新的实现?我认为后者?
  3. 我打算覆盖子类中的hashCode方法。再次调用超类hashCode方法最好有一个新的实现吗?我本来打算 将子类equals方法中的a,b和c与另一个对象进行比较,并在子类hashCode方法中为b和c创建哈希码?这是要走的路还是要求我只考虑子类equals和hashcode方法中的变量c?
  4. 我已经看过各种资源,包括bloch的Effective Java(第3章),但找不到上述问题的答案

4 个答案:

答案 0 :(得分:3)

这个答案假设你的班级看起来像这样:

public class MySuperClass {
    int a,b;
}

public class MySubClass extends MySuperClass {
    int b;
}

首先,您的评论toString()与主要问题无关。在任何情况下,您的代码都不应该依赖于toString实现 - 它仅为人类输出。但是请随意使用super impl:

public String toString() {
    return super.toString() + ", c=" + c;
}

其次,equals()应该比较对象的(已发布)状态。由于子类有另一个字段,因此它需要自己的equals()。但是,您可以使用超类的equals()方法,如下所示:

public boolean equals(Object o) {
    // The super equals() will compare int a and int b for us
    if (!super.equals(o)) {
         return false;
    }
    // super thinks it is equal, so let's compare int c
    return o instanceof MySubClass && ((MySubClass)o).c == c;
}

第三,hashcode应该与equals对齐,所以也要实现它。同样,你可以使用super的impl来加剧a和b:

public int hashcode() {
    return super.hashcode() + new Integer(c).hashCode(); // for example
}

答案 1 :(得分:1)

只要子类中的所有内容都存在于超类中,就不需要覆盖它们(当然,除非你想要一些不同的功能)。

基本上,如果您希望每个子类具有不同的功能,则只覆盖该方法。

但是,当然,你说你的子类有一个新变量int c。在这种情况下,您需要覆盖该方法以获得完整的功能,尤其是equals()hashCode()

答案 2 :(得分:0)

这取决于您尝试表示的内容以及您当前equalshashCode方法的用途。除非您希望将子类添加的新字段考虑在内,否则您不需要重写,如果您的超类方法对于扩展类的可能性不稳定(例如,比较obj.getClass()而不是使用instanceof)。

答案 3 :(得分:0)

如果要正确表示对象的哈希值,则需要覆盖equals和hashCode。如果你不覆盖hashCode(),那么只会因新字段 c 中的差异而变化的对象都将被放入相同的哈希桶中(如果你覆盖hashCode,那么你必须覆盖equals,因为两个等于的对象必须具有相同的哈希)。您的hashCode实现可以使用超类实现并将其添加到其他子类字段。

不幸的是,对于一个非抽象类的子类并为其添加新字段的类,不可能编写严格正确的equals函数。你要么最终破坏equals的一些契约属性,要么只使用添加方法的子类也最终不平等。

推荐的解决方法是不要为了添加字段而进行子类化,而是创建一个包含父类的实例和新字段的复合类,并导出包含的视图如果需要,可以对它进行比较。