[英]What should compareTo() return if argument is different implementation of the same interface?
Having interface 有界面
interface Animal extends Comparable<Animal> {
}
and 2 classes 和2节课
class Dog implements Animal {
}
and 和
class Cat implements Animal {
}
What compareTo(Animal o)
should return when arguement is not the same concrete implementation of Animal
? 如果争论与
Animal
具体实现不同,应该返回什么compareTo(Animal o)
?
Should it throw IllegalArgumentException
? 它应该抛出
IllegalArgumentException
吗?
As example if I pass Dog
instance to Cat.compareTo()
. 例如,如果我将
Dog
实例传递给Cat.compareTo()
。 I can not compare them as they are different types. 我无法比较它们,因为它们是不同的类型。 I can not refer to
super.compareTo()
as their super is Object
type which doesn't implement Comparable
. 我不能引用
super.compareTo()
因为它们的super是没有实现Comparable
Object
类型。 Casting Dog
to Cat
will throw ClassCastException
. 将
Dog
投射到Cat
会抛出ClassCastException
。
interface Animal
shouldn't be implementing Comparable<Animal>
in the first place if you don't want its subclasses to be mutually comparable. interface Animal
不应该被执行Comparable<Animal>
在第一个地方,如果你不希望它的子类是相互比较。
There is a relevant quote from Effective Java 2nd Ed , in Item 8 "Consider implementing Comparable" (I copied much of the following from my answer to this question ): 在有效的Java 2nd Ed中 ,在第8项“考虑实现Comparable”中有一个相关的引用(我从对这个问题的回答中复制了以下内容):
One consequence of these three provisions [of the
compareTo
contract] is that the equality test imposed by a compareTo method must obey the same restrictions imposed by the equals contract: reflexivity, symmetry, and transitivity.[
compareTo
契约]的这三个规定的结果是,compareTo方法施加的相等性测试必须服从平等契约所施加的相同限制:自反性,对称性和可传递性。 Therefore the same caveat applies: there is no way to extend an instantiable class with a new value component while preserving the compareTo contract, unless you are willing to forgo the benefits of object-oriented abstraction (Item 8).因此,同样的警告也适用:在保留compareTo协定的同时,无法用新的值组件扩展可实例化的类,除非您愿意放弃面向对象抽象的好处(第8项)。
So, what this says is that provided your subclass doesn't have any more values than the superclass used to determine ordering , implementing Comparable<Supertype>
is reasonable. 因此,这就是说, 如果您的子类没有比用于确定ordering的超类更多的值 ,则实现
Comparable<Supertype>
是合理的。
The implication of this, in addition to the general requirements of the Comparable
, is that Comparable<Superclass>
should be implemented identically in Superclass
and all subclasses. 除了对
Comparable
的一般要求外,其含义是,应该在Superclass
和所有子类中以相同的方式实现Comparable<Superclass>
。
When you define Ainimal
as: 当您将
Ainimal
定义为:
interface Animal extends Comparable<Animal> {
}
you're saying that any Animal
can be compared to another Animal
. 您的意思是任何
Animal
都可以与其他Animal
进行比较。
If you only want to compare Dog
to Dog
, you should define it this way: 如果只想将
Dog
与Dog
进行比较,则应采用以下方式进行定义:
interface Animal {
}
class Dog implements Animal, Comparable<Dog> {
@Override
public int compareTo(Dog o) {
...
}
}
The comparable
interface only states some things how to work together with 'equals', for example, that compateTo()
should return 0 if equals
returns 0. https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Comparable.html 在
comparable
接口只规定一些事情是如何协同工作以“等于”,例如, compateTo()
是否应该返回0, equals
返回0 https://docs.oracle.com/javase/8/docs/api/index .html?java / lang / Comparable.html
So actually it depends. 所以实际上这取决于。 If it makes sense to your program, you could cast to
Animal
: 如果对您的程序有意义,则可以转换为
Animal
:
int compareTo(Dog o)
{
Animal other = (Animal) o;
...
}
So if you want to sort Animal for size or for the number of search results on Google by using compareTo
this would be a valid implementation. 因此,如果您想通过使用
compareTo
来对Animal进行大小或Google搜索结果数量的排序,这将是一个有效的实现。
It really depends of whether you want to be able to compare a Cat and a Dog. 这实际上取决于您是否想要比较猫和狗。 Broadly speaking, there are different possibilities
广义上讲,存在不同的可能性
Compare all Animal instances with an order consistent with Equal 比较所有动物实例的顺序是否等于Equal
You could for example use different attributes of animals in a way that 2 different animals cannot have all attributes the same. 例如,您可以使用动物的不同属性,即两种不同的动物不能具有相同的所有属性。 If it makes sense you can use the class name as such an attribute to compare a Cat and a Dog having all other attributes identical
如果可以的话,您可以将类别名称用作此类属性,以比较所有其他属性相同的Cat和Dog
Compare all Animal instances with an order non consistent with Equal 比较所有动物实例的顺序与等于不一致
Just a slight variation of the above: two animal will compare equal if their attributes are identical, even if equals
between them will return false. 上面的内容略有不同:如果两个动物的属性相同,则它们将比较相等 ,即使它们之间的
equals
将返回false。 Beware, it may be dangerous (even if possible), according to the Javadoc for Comparable 请注意,根据Javadoc for Comparable ,它可能很危险(即使可能)。
It is strongly recommended (though not required) that natural orderings be consistent with equals.
强烈建议(尽管不是必需的)自然顺序应与等号保持一致。 This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals.
之所以如此,是因为没有显式比较器的排序集(和排序映射)与自然排序与等式不一致的元素(或键)一起使用时,其行为“奇怪”。 In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.
特别是,这样的排序集(或排序图)违反了根据equals方法定义的集合(或图)的一般约定。
Only compare Animal instances in one class (and of course its subclasses). 仅在一个类(当然还有其子类)中比较Animal实例。 In that case, the declaration of the interface should be changed to use generics:
在这种情况下,应该将接口的声明更改为使用泛型:
interface Animal<T> extends Comparable<T> { }
and 2 classes 和2节课
class Dog implements Animal<Dog> { }
and 和
class Cat implements Animal<Cat> { }
它应该引发不匹配错误,如果可能的话,在比较之前使用instanceOf运算符匹配相关对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.