简体   繁体   English

如果参数是同一接口的不同实现,则compareTo()应该返回什么?

[英]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: 如果只想将DogDog进行比较,则应采用以下方式进行定义:

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 广义上讲,存在不同的可能性

  1. 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

  2. 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方法定义的集合(或图)的一般约定。

  3. 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.

相关问题 当参数字符串为 null 时,int compareTo() 应该返回什么? - What should int compareTo() return when the parameter string is null? Java:compareTo接口的语义是什么? - Java: What are the compareTo interface semantics? 返回与传入相同的接口实现的方法 - Method to return the same interface implementation as passed in 我应该将接口声明为返回值还是将实现声明为返回值? - Should I declare the interface as the return value or the implementation as the return value? compareTo() 实际上返回什么? - What does compareTo() actually return? Java compareTo方法。 student.compareTo方法应返回 - Java compareTo method. The student.compareTo method should return 在Spring JavaConfig中,bean返回类型应该是接口还是实现? - In Spring JavaConfig, should the bean return type be the interface or implementation? 接口方法应该返回什么类型 - What should be return type in interface method 如何访问同一接口的不同实现的不同属性 - How to access different attributes of different implementation of the same interface Java如果我具有不同的构造函数但具有相同的接口,则应为对象实例化使用哪种设计模式? - Java what design pattern should I use for object instantiation if I have different constructor but same interface?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM