簡體   English   中英

在超類或子類中覆蓋equals和hashCode方法,或在兩者中覆蓋

[英]Override equals and hashCode methods in superclass or in the sub class or override in both

我是Java編程的新手,當我有一個從超類繼承的子類時,發現在哪里使用equals和hashcode方法覆蓋時遇到了問題。

我想檢查超類和子類的對象是否相等,並且想知道超類和子類中的一個或兩者是否都需要它們的equals和hashcode方法覆蓋?

我的子類沒有實例變量,而我的超類有2個實例變量(整數)

我的子類構造函數正在調用超類構造函數。

如果我想重寫子類equals和hashcode方法,那么基於該子類沒有實例變量而是從其超類繼承2個實例變量的事實是可能的嗎?

這實際上提出了一個難題。 假設您有一個Foo類,以及兩個子類FooA和FooB。 在您的應用程序/域中 ,使FooA等於Foo或FooB是否有意義?

如果是這樣,則應在超類中實現equals。 並測試instanceof Fooinstanceof 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。 例如

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撰寫的有效Java 您會發現很多關於此的文章,例如,在生成.equals()時,有什么理由要比instanceof更喜歡getClass()嗎?

您需要為類重寫它們,其對象在運行時將處於equals()檢查之下,或者其對象將/可能處於基於哈希的數據結構之下

由於沒有在子類中添加任何新屬性,因此在超類中覆蓋equals()hashcode()會很好。 當您在子類對象上調用這些方法時,將不會調用超類方法,而從Object類調用這些方法

但是,如果以后再將新屬性添加到子類中,則還需要重寫子類中的那些方法。

如果我想重寫子類equals和hashcode方法,那么基於該子類沒有實例變量而是從其超類繼承2個實例變量的事實是可能的嗎?

這當然是可能的 ,但幾乎沒有道理。 請注意, equals()的協定要求它是對稱的 ,即a.equals(b)b.equals(a)始終應具有相同的結果。 ab是分別定義equals()的子類和超類的實例時,可能不會保留此協定。 這意味着,如果將兩個類的實例放入集合中,則該集合可能無法正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM