Let’s say we have 4 classes A, B, C, D where: A is a superclass of both B and C and C is a superclass of D. I suppose, in a diagram, it should look like this:
A
/
B C
D
Moreover, the class A implements the interface
Comparable<A>
and also implements a method
public int compareTo(A another)
I’d like to be able to compare every pair of objects x, y such that they are instances of classes from the set {A, B, C, D}. Naturally, I should implement a compareTo method in each of these classes but by default I’m doing this with one sided effect, i.e. defining how to compare object c from C with b from B doesn’t tell anything about how to compare b with c.
Now, I could write a lot of code and handle all of those cases (this also means I would have to use ‘isInstance’ method to handle these, right?) but then every two classes have to be ‘aware of’ existence of others. So if I wanted to add another class, E, such that D is a superclass of E, I would have to serve all cases in the new class E and moreover I’d have to change something in classes A, B, C, D in order to ‘be aware of E’.
So I’m struggling to find an elegant solution to it, i.e. one that doesn’t entail changing a lot while adding a new class to the hierarchy.
How can I achieve this?
Thank you in advance for help.
2
You could write a general compareTo
method in class A
, which uses a key computed by a method compareKey
which is also in A
, but can be overridden by each subclass to make as fine a distinction as it wants. If you make it return a float, you can keep subdividing the comparison criterion whenever a new level of inheriting classes is added (within reason, obviously).
4
I think what you want is sort of multiple dispatch which is ususally implemented in Java using the Visitor-Pattern but you would have to change the code when adding new classes.
Since you don’t really need full-blown multiple dispatch I think the following might be a good solution. Write your compareTo methods like this: (This is the one in TestB)
@Override
public int compareTo(TestA o) {
if(o instanceof TestB) {
// add your code instead
System.out.println("Compare Bs");
return 0;
} else {
return super.compareTo(o);
}
}
Since the call to x.compareTo is resolved at run-time you always run the compareTo function of the most specific class. By checking if the other argument is instanceof the current class you can detect when you have to move up the hierarchy which you can do calling super.compareTo.
Let me know if you have any further questions. 🙂
Edit: I assumed what you wanted to do was compare as the most specific common ancestor as per your comment on the original question.