This is not a good idea, as a design pattern. And, by the way, it is impossible in Java, because Comparable and Comparable are the same binary interface due to type erasure.
Anyway, I'll try to explain why I think that's a bad idea. When you implement Comparable
you are defining a so-called "natural sorting", which is a sorting intrinsic to the class itself, a natural ordering. This ordering should involve the class and elements of the same class. So, I think (and this is a purely personal opinion) that you should only implement Comparable
with the same class as the one you're implementing.
If you want to compare segments with points, this is of course a perfectly legitimate thing, as long as you have a well-defined ordering. You can achieve that by implementing a so-called "external comparator", i.e. a class that implements Comparator<X>
, where X is a common superclass of Point
and Segment
. Java standard classes and functions are prepared to always accept an optional external comparator, because, in general, you might want to have different sorting criteria for objects of the same class.
You seem not to have a common base class/interface. Maybe you should define one, they're both geometrical entities, after all. As of now, the only thing you can do is use Comparator<Object>
, and then use the instanceof
operator to check the types. Which is a lot of boilerplate code, and also, I think, bad design: since you're saying the points and segments are comparable, they should have some common property that you wish to compare. Then this property should become a method of a common base class or an interface they both implement (which, indeed, might lead you to use Comparable
again, but in a cleaner way).
For instance, assume that you want to compare points and segments based on their coordinates, and you want the median of a segment to be considered in sorting. Then, you could do something as:
public abstract class GeometricEntity implements Comparable<GeometricEntity> {
protected abstract Point getSortingPoint();
@Override
public int compareTo(GeometricEntity other) {
//Compare by getSortingPoint
}
}
public class Point implements GeometricEntity {
@Override
protected Point getSortingPoint() { return this; }
}
public class Segment implements GeometricEntity {
private Point ptFrom;
private Point ptTo;
@Override
protected Point getSortingPoint() { return meanPoint(ptFrom, ptTo); }
}