【发布时间】:2016-10-07 14:51:45
【问题描述】:
如果我有一个复杂的继承层次,并且我想做一个取决于特定相等性的相等性检查,有没有办法确保我使用该相等性检查而不是被可能表现不同的子类覆盖的版本运行那我要吗?
举个例子,假设我有一个带有它自己的相等类的 foo,然后我有一个类似 boo 的东西,它有一个类似于下面 sudocode 的 equals 类(懒得把它完全纠正)
class Foo {
int id;
int otherId;
int count;
public boolean equals(Object other){
//check other instance of foo and re-cast
return (id==other.id && otherId==other.otherId)
}
}
class Bar extends Foo{
private someObject uniqueValue;
public boolean equals(Object other){
//check other instance of foo and re-cast
return super.equals(other) && other.getUniqueValue.equals(this.getUniqueValue);
{
}
然后我有一些方法,它采用引用相同 foo 的太 foo 对象并将它们的计数相加
public combineFoos(Foo foo1, Foo foo2){
if(! foo1.equals(foo2))
throw IllegalArgumentException("no match");
Foo combinedFoo=new Foo(foo1.id, foo1.otherId, (foo1.count + foo2.count))
return combinedFoo
}
}
理论上,这一切都有效,直到 bar 值出现。现在,如果我调用 combineFoo 并将 bar 传递给 foo1,它会失败,因为 bar equal 方法检查 foo2 是一个 instanceOf bar。我真的不在乎 foo2 是否是 bar,我需要的信息可用于任何 foo。就此而言,如果我传入两个不相等的条,它们都由 foo 的相等方法定义(即只有 uniqueValue 字段不同),我希望 combineFoo 仍然接受它们作为相等的 Foo,即使 Bar 的定义不相等。
问题是我想对 FOO 认为什么是平等的进行平等检查,但我不知道我实际上可能收到什么奇怪的继承类。有没有办法解决这个问题,基本上在我的 combineFoo 中说始终使用等于的 FOO 定义,即使它被子类覆盖?
相关,这是一个比我想象的更糟糕的想法,即使它是可行的,或者是否有其他方法来处理类似上述示例的事情,除非在 combineFoo 中有效地重写 foo 的 equal 方法?
【问题讨论】:
-
Equals不是equals。使用正确的方法。 -
您的代码有很多错别字,无法按原样编译,难以聚焦实际问题。
-
@tunaki 正如我所说的它只是 sudocode,我将 cmets 留在了部分逻辑中。我只是想从概念上证明差异。我认为不需要运行它来理解这个概念吗?
-
如果类
foo有自己的equals行为并且您可以控制调用它(而不是被其他代码调用,例如Collection#contains),那么您可以添加foo的另一种方法,您声明final(因此它不能在子类中被覆盖),例如public final boolean fooEquals(foo other) { // custom foo equals logic }. -
恕我直言,您来自 Bar 的 equals 方法不会检查 foo2 的实例,而是从 foo 调用 equals,不是吗?无论如何,您可以通过 forret 的想法或仅通过为 foo 而不是为 bar 定义 equals 方法来获得您的行为。如果你有一个 bar 调用 equals,它应该使用 foo 之一。
标签: java polymorphism equality