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.