Best practice for compareTo () when an argument needs to be entered in a superclass

I am looking for best practice for defining the compareTo () method when the class implements Comparable. Thus, the method signature should be

public int compareTo(BaseClass arg) 

The obvious thing to do first is to check if the arg argument is an instance of this class, and if so, add it to the class and compare it. But if the argument does not apply to this class, but rather to another class that also implements BaseClass, what do I return to be reflective?

I know the best practices would be to define compareTo () only for the class that it is, but the water is above the dam.

+4
source share
3 answers

Quoting from Effective Java, Paragraph 12:

Let's take a look at the provisions of the compareTo contract. The first position says that if you change the direction of comparison between two objects, the expected thing happens: if the first object is smaller than the second, then the second should be larger than the first; if the first object is equal to the second, then the second should be equal to the first; and if the first object is larger than the second, then the second should be less than the first. the second position says that if one object is more than a second and the second is more than the third, then the first should be more than the third. The last provision states that all objects are compared, since an equal should give the same results compared to any other object.

One consequence of these three points is that the equality test imposed by acompareTo must obey the same restrictions imposed by equivalent contracts: reflexivity, symmetry, and transitivity. Therefore, the same caveat applies: it is not possible to extend a class with a new value component while maintaining Compare the contract if you are not ready to give up the benefits of an object-oriented abstraction (paragraph 8). The same workaround applies, too. If you want to add a value component to a class that implements Comparable, do not distribute it; write an unrelated class containing an instance of the first class. Then specify the “lookup” method that this instance returns. This frees you from implementing any compareTo method that you like in the second class, allowing your client to view an instance of the second class as an instance of the first class if necessary.

You should do what @BalusC recommended in your comment - use the compareTo () method of the base class for all child classes, OR make the workaround suggested above by creating an unrelated class containing an instance of the first class.

+3
source

Your mistake is in your question. You do not need to implement public int compareTo(BaseClass arg) . You must implement "public int compareTo (YourClass arg)".

In this case, you do not need to use instanceof and do the translation. That's why generics were introduced: to avoid casting.

But if you still want to use the base class as an argument, do at least the following:

 public class Test { } class SubTest <T extends Test> implements Comparable<T> { @Override public int compareTo(T o) { // add your code with instanceof here return 0; } } 

At the very least, this approach requires the argument to be a subclass of your base class.

+2
source

In this context, reflective means obj.compareTo(obj) == 0 . What do you mean by reflexivity here?

As for the specified contract for compareTo (T o), the required semantics are to throw a ClassCastException if the corresponding classes cannot be meaningfully matched.

eg. Considering,

 class Fruit {/* ..*/ } class Apple extends Fruit {/* .. */ } @Ignore("bad OO") class GrannySmithApple extends Apple {/* .. */ } class Orange extends Fruit {/* ... */ } 

it can be argued that

  Fruit a = new Apple(); Fruit b = new GrannyApple(); Fruit c = new Orange(); // compare apples with apple? // makes sense to expect an int value r = a.compareTo(b) // compare apples with oranges? // makes sense to expect an exception boolean excepted = false; try { c.compareTo(a); } catch (ClassCastException e) { excepted = true; } finally { assert excepted : "How can we compare apples with oranges?" } 
+1
source

All Articles