/*
interface Comparable {
  int compareTo( Object o );
  // int compareTo( Comparable o );
}
class A implements Comparable {
  int compareTo( Object o );        // "binary-method"
}
class B implements Comparable { 
  int compareTo( Object o );
}
... new A().compareTo(new B()) ...


interface Comparable<T> {
  int compareTo( T o );
}
class A implements Comparable<A> {
  int compareTo( A a );
}
class B implements Comparable<B> { 
  int compareTo( B b );
}
... new A().compareTo(new B()) ...    compilation error
*/

/* 
class Point implements Comparable<Point> {       // generic code
   double x, y;
   Point( double x, double y ){ this.x = x; this.y = y; }
   public String toString(){ return x + "," + y; }
   public boolean equals( Object o ){
     if( o != null && o instanceof Point ){
        Point p = (Point) o;
        return x == p.x && y == p.y;
     } else return false;
   }
   private double distanceSquare(){ return x*x + y*y; }
   public int compareTo( Point p ){
       return (int) Math.signum( distanceSquare() - p.distanceSquare() );
   }
}
*/

class Point implements Comparable {      // after erasure
   double x, y;
   Point( double x, double y ){ this.x = x; this.y = y; }
   public String toString(){ return x + "," + y; }
   public boolean equals( Object o ){
     if( o != null && o instanceof Point ){
        Point p = (Point) o;
        return x == p.x && y == p.y;
     } else return false;
   }
   private double distanceSquare(){ return x*x + y*y; }
   public int compareTo( Point p ){
       return (int) Math.signum( distanceSquare() - p.distanceSquare() );
   }
   public int compareTo( Object o ){    // "bridge method" generated
       return compareTo((Point)o);      // might conflict with overloading
   }
}


/*
class ColoredPoint extends Point implements Comparable<ColoredPoint> {       // illegal: compilation error
   int color;
   ColoredPoint( double x, double y, int color ){ super(x,y); this.color=color; }
   public String toString(){ return super.toString() + "/" + color; }
   public boolean equals( Object o ){
     boolean se = super.equals(o);
     if( se && o instanceof ColoredPoint ){
        return  color == ((ColoredPoint)o).color;
     } else return se;
   }
   public int compareTo( ColoredPoint p ){
       int d = compareTo((Point)p);
       return (d == 0) ? color - p.color : d;
   }
}
*/


class ColoredPoint extends Point implements Comparable {       // after type erasure
   int color;
   ColoredPoint( double x, double y, int color ){ super(x,y); this.color=color; }
   public String toString(){ return super.toString() + "/" + color; }
   public boolean equals( Object o ){
     boolean se = super.equals(o);
     if( se && o instanceof ColoredPoint ){
        return  color == ((ColoredPoint)o).color;
     } else return se;
   }
   public int compareTo( ColoredPoint p ){
       int d = compareTo((Point)p);
       return (d == 0) ? color - p.color : d;
   }
   public int compareTo( Object o ){        // "bridge method" generated
       return compareTo((ColoredPoint)o);   // overrides inherited bridge method
   }                                        // Or there should be no bridge method here?
   /*
   public int compareTo( Point p ){
       return (int) Math.signum( distanceSquare() - p.distanceSquare() );
   }
   */
}


class G34 {
   public static void main( String[] args ){
       ColoredPoint target = new ColoredPoint(1,1,1);
       ColoredPoint cp = new ColoredPoint(1,1,1);
       Point p = cp;
       target.compareTo(cp);    // different methods are called
       target.compareTo(p);
   }
}