【发布时间】:2013-11-25 23:01:14
【问题描述】:
我一直在测试一段代码,偶然发现一个问题:你是否应该在子类中调用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 对象时,调用 super 方法并将 item.getPrice() 动态分派到子类 DiscountedItem 中的正确方法,而其他价格值则使用变量直接访问。
那么,这真的取决于我(因为我应该正确实施该方法)还是有办法解决它?
【问题讨论】:
-
您的子类的
equals方法应该以与该方法的约定一致的方式实现。委托给super.equals()的原因是子类可能无法访问super.equals()可能依赖的父类的字段。如果你违反封装,所有的赌注都会被取消。如果您通过使子类违反其父类的合同而未能很好地实现super.equals(),那么再次,所有的赌注都没有了。 -
有人可能会说,这里的根本问题是在 bean getter 中嵌入业务逻辑,而不是更学术的问题 :)
-
@Affe 哦,这甚至不是一个真正的 Web 应用程序,它只是软件测试课上给出的一个学术示例 :) 但我不认为这个错误是故意的..
-
This 相关
标签: java inheritance equals