It seems like you usually implemented the java.lang.Comparable
interface without specifying the type parameter.
public abstract class Area implements Comparable {
@Override
public int compareTo(Object other) {
if (other instanceof Area)
return new Double(getArea()).compareTo(other.getArea());
return -1; // or something else
}
abstract public double getArea();
}
Since I only want to compare apples with apples, I think it would make sense to specify the type.
public abstract class Area implements Comparable<Area> {
@Override
public int compareTo(Area other) {
// ...
If I want to introduce another class to compare Area
with, I thought I could do the following:
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
@Override
public int compareTo(Area other) {
// ...
}
@Override
public int compareTo(Volume other) {
// ...
}
}
But the java compiler tells me:
Area.java:2: error: repeated interface
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
^
Area.java:2: error: Comparable cannot be inherited with different arguments: <Area> and <Volume>
Note: I'm using Java version 1.7.0_45
No, it's not a drawback of specifying the generic - it's actually a feature. Also, I don't recall any drawback for using generics in interfaces, other than the well-known fact you can't instantiate a generic type nor create a generic array (but that's more a problem of implementation, not the interface itself).
It's due to type erasure. Comparable<Area>
and Comparable<Volume>
is essentially the same class for the VM, and, shortly after checking validity, also for compiler.
If you want to have two distinct comparable interfaces implemented, just use Comparator
s for them - it's generally easier to maintain composition than inheritance in classes.
For some applications (distinguishing generics at run-time) you may also try subclassing them, e.g. ComparableArea extends Comparable<Area>
& ComparableVolume extends Comparable<Volume>
, but that would, in this particular case, cause more trouble than it would solve IMO, since you'd still get Comparable cannot be inherited with different arguments
error - but at least you could differentiate those interfaces by e.g. instanceof
.