2011-12-13 30 views
1

我有一個擁有2個實例變量的超類(比如int aint b)和 現在已經決定我需要在我的子類int c中有一個實例變量。Overriden等於和超類的哈希碼方法。我是否爲子類做

我已經覆蓋超類equals和hashCode方法來考慮 對象/值的相等性。我還覆蓋了超類toString,以給出表示對象狀態(變量值)的字符串 。

基於以上的事實我現在有一個實例變量int下,在我的子類 我在想,如果我

  1. 需要重寫子類中的toString方法,或者這是一種沒有沒有因爲我在超類中有一個有效的可繼承的toString方法(已重寫),可用於子類字符串表示?
  2. 需要重寫子類中的equals方法。通過調用superclass equals方法並在調用後爲我的子類實例變量添加比較代碼,還是需要新的實現,可以完成 ?我認爲後者?
  3. 我打算重寫子類中的hashCode方法。再次調用超類hashCode方法最好有一個新的實現?我打算 將子類equals方法中的a,b和c與另一個對象進行比較,並在子類hashCode方法中爲b和c創建哈希碼?這是要走還是要求我只考慮子類equals和hashcode方法中的變量c?

我有一個瞭解各種不同的資源,包括有效的Java布洛赫(第3章),但無法找到這個問題的答案我有上述問題

回答

1

只要一切在子類中存在超類,沒有必要重寫它們(除非,當然,你想要一些不同的功能)。

基本上,只有重寫方法,如果你想爲每個子類的不同功能。

但當然,你說你的子類有一個新的變量,int c。在這種情況下,您需要重寫該方法才能具有完整的功能,特別是對於equals()hashCode()

0

這取決於您想要表示什麼,以及您目前的方法是什麼equalshashCode。除非您希望將子類添加的新字段考慮在內,否則您並不需要重寫,如果您的超類方法對擴展類的可能性不穩健(例如,比較obj.getClass()而不是使用instanceof)。

3

這個回答假設你的類是這樣的:

public class MySuperClass { 
    int a,b; 
} 

public class MySubClass extends MySuperClass { 
    int b; 
} 

首先,您的意見重新toString()是風馬牛不相及的主要問題。無論如何,你的代碼不應該依賴toString實現 - 它的輸出只適用於人類。隨意但是使用超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一致,所以也實現它。同樣,你可以用超級的IMPL該散列了a和b:

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

您的equals方法違反Object.equals強制的symmetry屬性,可能不應使用它。 superclass.equals(子類)將返回true,而subclass.equals(超類)將返回false。 –

+2

你可以用'c'替換'new Integer(c).hashCode()'。 –

0

如果要正確地表示對象的哈希值,那麼你需要同時重寫equals和hashCode。如果你不重寫hashCode(),那麼只會因你的新字段差異而變化的對象將全部放入同一個散列桶(如果你重寫hashCode,那麼你必須重寫equals,因爲兩個相等的對象必須有相同的哈希)。您的hashCode實現可以使用超類實現並將其添加到其他子類字段中。

不幸的是,不可能爲一個非抽象類的子類編寫嚴格正確的equals函數,並向它添加一個新字段。你最終可能會破壞一些等價的合約屬性或者使得只有添加方法的子類最終不平等。

建議的解決方法是不要爲了添加字段而創建子類,而是要創建一個組合類,其中包含父類的實例以及新字段,並且還會導出包括類,因此可以在需要時進行比較。