/*
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 {
   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( Point p ){
       int d = super.compareTo(p);
       return (p instanceof ColoredPoint && d == 0)
              ? color - ((ColoredPoint)p).color
              : d;
   }
}