2011-12-15 30 views
2

我有一個超類有兩個變量(int a)(int b),並有一個子類,通過改寫2超類方法擴展超類的功能,改進方法現在在子類中。作爲我的子類的一部分,我現在有一個新的intint c),它是一個唯一的ID(UUID)。Overriden Superclass Equals和HashCode,並認爲我應該這樣做與子類

我明白了平等很難與equals方法

我可以覆蓋超equalshashCode方法,以顯示平等維護,也做了子類equalshashCode方法同樣基於上述我的情況?

我最初覆蓋了超類中的equalshashCode方法。如果它也應該由子類中的額外實例變量(int c)爲子類完成。我知道應該有一個hashCode方法來顯示這一點,並且如果haschCode被更改,那麼equals方法的子類必須更改?

我真的很困惑,最好做什麼。

我在想,如果我的超類equalshashCode方法能顯示平等關係嗎?它是允許連同我的超equalshashCode重寫的方法,該子類可以顯示爲等於int aint bint c和子類的hashCode方法更新,以顯示int小號abc獨特的散列碼進行比較?

我想在這兩個變量的超equals方法和更新哈希碼和int S表示這些變量3 abcequals方法,更新哈希碼進行比較我int小號ab的。超級中的int c是唯一的嗎?

非常感謝這裏的任何建議,因爲我相信忽略和不處理子類equalshashCode中的int c方法可能是一個不行。

在此先感謝

+4

hashcode和equals的合約說如果a和b的hashCode()函數的a.equals(b)應該返回相同的值。反過來並不需要是真的。 – 2011-12-15 15:23:47

回答

1

基本上,你有兩個可能的選擇:

  1. 忽略c乾脆。根據ab定義超類的相等性,並且不要在子類中覆蓋它。

  2. 始終將超類和子類的實例視爲不相等。它允許您在超類(基於ab)和子類(基於a,bc)中以不同的方式定義相等性。

    注意,在子類中重寫equals()hashcode是不夠的,在這種情況下 - 還實現超類的equals()方法時,需要一個特殊的技巧,看到有關How to Write an Equality Method in JavacanEquals()方法的一部分。

1

問題的癥結在於是否希望它可以用於超類的實例和子類的實例進行比較。

如果是這樣,請勿覆蓋equals()hashCode()方法。你甚至可以在超類中使它們成爲final

如果不是,則每個類的equals()方法應使用getClass()而不是instanceof檢查參數的類型爲equals()。例如,在超:

if ((obj == null) || (!getClass().equals(obj.getClass())) 
    return false; 
/* Compare a and b. */ 
... 

在子類:

if (!super.equals(obj)) 
    return false; 
/* Compare c. */ 
... 

如果散列碼是基於ab領域,你可能不會有覆蓋hashCode()方法,但如果您在子類的實現中確實考慮了c,那麼您的類可能會更好地作爲關鍵字。也就是說,它會將具有不同值c的密鑰放入不同的桶中,而不是將相同的ab的所有實例聚合在同一個哈希桶中。

0

++給Jordan Bently。

對於您編寫的每個類,覆蓋equals(),toString()hashCode()通常是一個好主意。在實踐中,這並不總是合情合理的。但是對於你在做什麼,我會這樣做。是的,您可以更改子類中的實現。

@Override標記每個覆蓋方法以幫助向您所覆蓋的開發人員提供文檔是很好的做法。這提示他們,如果不是你的超級類,那麼你至少要重寫java.lang.Object

0

這取決於。比方說,你的超類是AB extends A則可能出現這種情況

  • a.equals(a)
  • b.equals(b)
  • a.equals(b)(真)? b.hash == a.hash:哈希並不重要
  • b.equals(a)(true)? b.hash == a.hash:哈希沒關係

應該怎麼樣AB有關?有兩個選項:

  1. AB是完全不同的,因此a.equals(b)b.equals(a)總是假。這是最安全的。你需要在等於測試a.getClass() == b.getClass();確保ab完全相同類型。例如,Eclipse IDE在生成equals()和hashCode()時默認自動生成這種類型的相等。
  2. AB能比的,但你不能忽略它在B保持的equals()合同hashCode().這是由於強制平等的對稱合同(a.equals(b) == b.equals(a))。
0

爲了確定hashCode和equals的行爲,需要考慮一些場景。

class Foo { int a, b; } 
class Bar extends Foo { int c;} 

是一個Foo和Bar用相同的a和b值相等(即,他們是否表示相同的值)?如果是這樣,那麼將equals和hashCode實現添加到Foo,並且不要在Bar中覆蓋它。在equals中,確保檢查對象是instanceOf Foo,而不是類相等。

是酒吧實例,其中不同的C的平等?如果是這樣,那麼不要重寫Foo的hashCode和equals的實現。

否則,你應該在Foo和Bar中都有equals和hashCode的實現。確保將其設計爲使Foo實例僅與其他Foo實例相同,並且Bar實例僅與其他Bar實例相同。如果沒有,你可以很容易地通過違反平等要求的對稱性,e.g

Foo x = new Foo(a,b); 
Bar y = new Bar(a,b,c); 
x.equals(y); //returns false 
y.equals(x); //returns true 

以上是很糟糕,而且會引起奇怪的行爲,例如,如果你把一個Foo和酒吧爲一組。

最後,你不應該寫你自己的hashCode的實現,並等於這些對象。大多數IDE都有自動生成工具,用它來代替。

相關問題