[英]What's wrong with using Inheritance Equality in Java?
在我正在閱讀的“ 核心Java卷1 ”一書中,它說平等不應該與繼承一起使用。 所以,我有以下示例,似乎有一些錯誤:
public class Main {
public static void main(String[] args) {
C c = new C("Test", 10);
D d = new D("Test", 10);
if (c.equals(d))
System.out.println("Equal");
else
System.out.println("Unequal");
if (d.equals(c))
System.out.println("Equal");
else
System.out.println("Unequal");
}
}
class C
{
C(String cstr, int cnum) {
str = cstr;
num = cnum;
}
@Override
public boolean equals(Object otherObject) {
// A quick test to see if the objects are identical.
if (this == otherObject) {
return true;
}
// Must return false if the explicit parameter is null
if (otherObject == null)
{
return false;
}
if (!(otherObject instanceof C))
return false;
// Now we know otherObject is a non-null Employee
C other = (C) otherObject;
// Test whether the fields have identical values
return str.equals(other.str) && num == other.num;
}
private String str;
private int num;
}
class D extends C {
D(String cstr, int cnum) {
super(cstr, cnum);
}
}
對於兩個對稱比較,它返回“等於”,這可能是不應該的。 是否在派生類'D'中缺少另一個equals
方法? 如果是這樣的話,那么上面的示例代碼可能會出現什么問題,如果我不使用另一個equals
派生它?
如果您希望實例C
和D
不與otherObject.getClass() != this.getClass()
進行相等替換!(otherObject instanceof C)
otherObject.getClass() != this.getClass()
。 這將確保只有C
可以等於另一個C
並且只有D
可以等於另一個D
這是否是你想要的取決於幾個因素。 我的一般經驗法則是,擁有一個“開放式”平等類是一個壞主意,“外部用戶”(無論對你來說意味着什么)可以添加到它。 如果您希望將不同類型的對象比較為相等(並且這種情況非常罕見),則應嚴格控制層次結構(例如,使用final
類)。
集合(和類似的明確定義的接口)是不同的:這里接口定義了一個非常精確的契約,所有實現類都需要遵循它(即如果它們都以相同的順序包含相同的元素,則ArrayList
可以等於LinkedList
,因為List
接口定義了兩個List
s相等的含義。
該代碼有效,因為正如您所說, D
不會覆蓋equals
。 我希望本書所提出的觀點是D
應該重寫equals
(並且它們都應該覆蓋hashCode
),因為D
實例不應該等於C
實例,因為它們是不同的(盡管是相關的)類型。
請記住, equals
合同的一個關鍵方面是對稱性 。 對於c
和d
任何非null
值,如果c.equals(d)
為真,則d.equals(c)
必須為真(和相反)。 雖然在你當前的代碼中也是如此,但它可能不應該是,因為D
和C
是不同的類型。 如果D
實例真的等同於C
實例,為什么有D
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.