我正在寻找关于覆盖子类中的hashcode和equals的指导。
我在这里找到了类似的问题:Overriding equals() & hashCode() in sub classes ... considering super fields
但我想要的是略有不同。
想象一下这个(有点愚蠢)的例子:
class Food {
String name;
@Override
public boolean equals(Object obj) {
if (obj instanceof Food) {
Food other = (Food)obj;
return name.equals(other.name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
class Vegetable extends Food {
// No additional fields here
// Some methods here
}
class Fruit extends Food {
// No additional fields here
// Some methods here
}
鉴于:
Fruit
和Vegetable
不应该相等问题:
instanceof
子类检查和对super.equals
的调用?Fruit
和Vegetable
个实例具有不同的哈希码,那么哈希码应如何构建?答案 0 :(得分:2)
您可以在.getClass()
Foo
中使用.equals()
:
@Override
public final boolean equals(final Object obj)
{
if (obj == null)
return false;
if (this == obj)
return true;
// Class<?> are signletons, therefore we can use ==/!=
if (getClass() != obj.getClass())
return false;
return name.equals(((Foo) obj).name);
}
.getClass()
将返回对象的类,因此Fruit
或Vegetable
,甚至Food
。
对于.hashCode()
,name.hashCode()
没问题。不要忘记不要求两个不是.equals()
的对象的哈希码不同。但如果你愿意,那么.getClass()
也可以在这里使用:
@Override
public final int hashCode()
{
return 31 * getClass().hashCode() + name.hashCode();
}
答案 1 :(得分:1)
- 您是否希望equals只包含一个检查实例和对super.equals的调用?
醇>
instanceof
在这里很危险,因为Food
不是抽象的。这意味着equals
不对称。
someFruit.equals(someFood) // will be false
someFood.equals(someFruit) // will be true
这可能不是转入问题,但这是你应该考虑的事情。
如果您不想违反合同,Food
应检查是否this.getClass() == obj.getClass()
。如果你这样做,那么你也不一定需要在子类中覆盖它。
否则它并不重要。该方法是按合同定义的,您可以根据需要实现它。
- 如何构建哈希码以尝试使用相同名称的Fruit and Vegetable实例具有不同的哈希码?
醇>
他们不需要与众不同。