title: A way to extend an instantiable class and add a value component while preserving the equals contract
body: <p><em>Effective Java</em> by Joshua Blotch states:</p>
  
  <blockquote>
    <p><strong>There is no way to extend an instantiable class and add a value component while preserving the <code>equals</code> contract,</strong> unless you are willing to forgo the benefits of object-oriented abstraction.</p>
  </blockquote>
  
  <p><em>Effective Java</em> gives some examples which either break <strong>symmetry</strong>, <strong>transitivity</strong> or <strong>Liskov substitution principle</strong>. <sub>I suppose you have read the item. I don't think I should post the whole item here.</sub> However I found a solution which obeys the contract:</p>
  
  <p>The <code>Point</code> :</p>
  
  <pre><code>public class Point{
      private final int x;
      private final int y;
      public Point(int x, int y){
          this.x = x;
          this.y = y;
      }
      protected boolean equalsImpl(Point p){
          return p.x == x &amp;&amp; p.y == y;
      }
      @Override
      public final boolean equals(Object o) {
          if(!(o instanceof Point))
              return false;
          Point p = (Point)o;
          return equalsImpl(p) &amp;&amp; p.equalsImpl(this);
      }
      // Remainder omitted ...
  }
  </code></pre>
  
  <p>The <code>ColorPoint</code> :</p>
  
  <pre><code>public class ColorPoint extends Point{
      private java.awt.Color color;
      public ColorPoint(int x, int y, java.awt.Color color){
          super(x, y);
          this.color = color;
      }
      @Override
      protected boolean equalsImpl(Point p){
          return (p instanceof ColorPoint) &amp;&amp;
                  super.equalsImpl(p) &amp;&amp;
                  ((ColorPoint)p).color == color;
      }
      // Remainder omitted ...
  }
  </code></pre>
  
  <p>I know composition should be used in this case, but I wonder <strong>whether my solution really obeys the <code>equals</code> contract</strong>. If yes, <strong>is what <em>Effective Java</em> states wrong</strong>?</p>