SWE 619 In Class Exercise # 9A
November 7, 2017


Consider Bloch's Point/ColorPoint example. For today, ignore the hashCode() issue.
public class Point {  // routine code
   private int x; private int y;    
   ...
   @Override public boolean equals(Object obj) {  // Standard recipe
      if (!(obj instanceof Point)) return false;

      Point p = (Point) obj;
      return p.x == x && p.y == y;
   }
}

public class ColorPoint extends Point {  // First attempt: Standard recipe
   private COLOR color;
   ...
  @Override public boolean equals(Object obj) {
      if (!(obj instanceof ColorPoint)) return false;

      ColorPoint cp = (ColorPoint) obj;
      return super.equals(obj) && cp.color == color;
   }
}

public class ColorPoint extends Point {  // Second attempt: DON'T DO THIS!
   private COLOR color;
   ...
   @Override public boolean equals(Object obj) {
      if (!(o instance of Point)) return false;

      // If obj is a normal Point, be colorblind
      if (!(obj instanceof ColorPoint)) return obj.equals(this);

      ColorPoint cp = (ColorPoint) obj;
      return super.equals(obj) && cp.color == color;
   }
}








  1. What is the equals() contract? What is the standard recipe?



  2. Why does Bloch use the instanceof operator in the standard recipe?



  3. Write client code that shows a contract problem with the first attempt at ColorPoint.



  4. Write client code that shows a contract problem with the second attempt at ColorPoint.



  5. Some authors recommend solving this problem by using a different standard recipe for equals().
    • What's the key difference?


    • Which approach do you want in the following code:
         public class CounterPoint extends Point
            private static final AtomicInteger counter =
               new AtomicInteger();
       
            public CounterPoint(int x, int y) {
               super (x, y);
               counter.incrementAndGet();
            }
            public int numberCreated() { return counter.get(); }
      
            @Override public boolean equals (Object obj) { ??? }
         }
      

      Client code:
          Point p = PointFactory.getPoint();   // either a Point or a CounterPoint
          Set<Point> importantPoints =   // a set of important points
          boolean b = PointUtilities.isImportant(p);  // value?