TIJ4 – compareTo() and inheritance – Tuple.java, exercise 28 from chapter 17

Solution guide for TIJ4 for exercise 28 from chapter 17 says:

When a class extends a concrete Comparable class (as T3<A,B,C>
extends T2<A,B> in the original program), and adds a significant
field, there is no way to simultaneously implement compareTo()
correctly. (…) The same holds true for equals()”

I did this exercise using inheritance as it was used in “original
program” and it works as well (?). In exercise some needs to implement
equals() method and Comparable interface.

public class TwoTuple<A extends Comparable, B extends Comparable> 
    implements Comparable {
  public final A first;
  public final B second;
  public TwoTuple(A a, B b) { 
    first = a; 
    second = b;
  }
  public String toString() {
    return "(" + toString2() + ")";
  }
  protected String toString2() { 
    return first + ", " + second;
  }
  public boolean equals(Object o) {
    return o != null && 
      o.getClass() == getClass() && 
      (first == null 
        ? getClass().cast(o).first == null 
        : first.equals(getClass().cast(o).first)) &&
      (second == null 
        ? getClass().cast(o).second == null
        : second.equals(getClass().cast(o).second));
  }
  public int hashCode() {
    int result = 17;
    if(first != null) {
      result = result * 37 + first.hashCode();
    }
    return second == null ? result : result * 37 + second.hashCode();
  }
  public int compareTo(Object o) {
    if(o.getClass() != getClass()) { 
      throw new ClassCastException();
    }
    int comparation = first.compareTo(getClass().cast(o).first);
    return comparation != 0 
      ? comparation 
      : second.compareTo(getClass().cast(o).second);
  }
}

public class ThreeTuple<A extends Comparable, B extends Comparable, C extends Comparable>
    extends TwoTuple<A, B>  {
  public final C third;
  public ThreeTuple(A a, B b, C c) {
    super(a, b);
    third = c;
  }
  protected String toString2() {
    return super.toString2() + ", " + third;
  }
  public boolean equals(Object o) {
    return super.equals(o) && 
      (third == null 
        ? getClass().cast(o).third == null 
        : third.equals(getClass().cast(o).third));
  }
  @Override
  public int hashCode() {
    int result = super.hashCode();
    return third == null ? result : result * 37 + third.hashCode();
  }
  @Override
  public int compareTo(Object o) {
    int comparation = super.compareTo(o);
    return comparation != 0 
      ? comparation 
      : third.compareTo(getClass().cast(o).third);
  }
}

Is my solution correct or I missed something?

To make it working I needed to skip generics implementing Comparable interface, so not this way:

TwoTuple(...) implements Comparable<TwoTuple> {
(...)
int compareTo(TwoTuple o) {

but just:

TwoTuple(...) implements Comparable {
(...)
 int compareTo(Object o) {

Maybe this is wrong statement which not obeying docs (?).


regards
Pawel