Having interface
interface Animal extends Comparable<Animal> {
}
and 2 classes
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
?
Should it throw IllegalArgumentException
?
As example if I pass Dog
instance to 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
. Casting Dog
to Cat
will throw ClassCastException
.
interface Animal
shouldn't be implementing Comparable<Animal>
in the first place if you don't want its subclasses to be mutually comparable.
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 ):
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. 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).
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.
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.
When you define Ainimal
as:
interface Animal extends Comparable<Animal> {
}
you're saying that any Animal
can be compared to another Animal
.
If you only want to compare Dog
to Dog
, you should define it this way:
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
So actually it depends. If it makes sense to your program, you could cast to 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.
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
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
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. Beware, it may be dangerous (even if possible), according to the 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.
Only compare Animal instances in one class (and of course its subclasses). In that case, the declaration of the interface should be changed to use generics:
interface Animal<T> extends Comparable<T> { }
and 2 classes
class Dog implements Animal<Dog> { }
and
class Cat implements Animal<Cat> { }
它应该引发不匹配错误,如果可能的话,在比较之前使用instanceOf运算符匹配相关对象。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.