我一直在測試一個代碼並偶然發現一個問題:你應該在子類中調用super.equals()
方法,該方法可以覆蓋一些用於equals()
超類的方法?繼承 - 在子類中使用super.equals()覆蓋在超類的equals方法中使用的方法
讓我們看看下面的代碼:
public abstract class Item {
private int id;
private float price;
public Item(int id, String name, float price, String category) {
this.id = id;
this.name = name;
this.price = price;
this.category = category;
}
public int getID() {
return id;
}
public float getPrice() {
return price;
}
@Override
public boolean equals(Object object){
if(object instanceof Item){
Item item = (Item) object;
if(id == item.getID()
&& price == item.getPrice())
{ return true; }
}
return false;
}
}
類和子類DiscountedItem:
public class DiscountedItem extends Item {
// discount stored in %
private int discount;
@Override
public boolean equals(Object object) {
if(object instanceof DiscountedItem){
DiscountedItem item = (DiscountedItem) object;
return (super.equals(item)
&& discount == item.getDiscount()
);
}
return false;
}
public int getDiscount() {
return discount;
}
@Override
public float getPrice() {
return super.getPrice()*(100 - discount);
}
}
我一直在剛剛重新閱讀Angelika Langer's secrets of equals(),她甚至說:
如果類有一個超類Object以外的類,應該調用super.equals()。
但我認爲當子類重寫某些方法時,這是非常不可預測的。例如,當我使用equals比較2個DiscountedItem
對象,超級方法被調用,item.getPrice()
動態分派到正確的方法在子類中DiscountedItem
,而其他價格值是使用變量直接訪問。
那麼,它是真的取決於我(因爲我應該正確實施該方法)還是有辦法解決它嗎?
您的子類的equals方法應該以與該方法的契約一致的方式實現。委託給super.equals()的原因是子類可能不能訪問super.equals()可能依賴的父類字段。如果您違反封裝,所有投注都將關閉。如果您通過讓子類破壞父類的合約來實現您的'super.equals()',那麼所有投注都將關閉。 – Floegipoky
有人可能會爭辯說,這裏的根本問題是將業務邏輯嵌入到bean獲取器中,而不是更多的學術問題。:) – Affe
@Affe噢,這甚至不是真正的Web應用程序,它只是軟件測試中給出的一個學術示例類:)但我不認爲這個錯誤是有目的的.. –