title: How to obey contract of equals() when deriving from abstract class
body: <p>In his book <em>Effective Java</em>, Joshua Bloch writes about the pitfalls that occur with the contract of <code>equals()</code> when derived classes add additional fields to the check. Normally, this would break the symmetry, but Bloch states that "you <em>can</em> add a value component to a subclass of an <em>abstract</em> class without violating the equals contract".</p>
  
  <p>Obviously this is true because there can be no instances of the abstract class, so there is no symmetry to violate. But what about other subclasses? I wrote this example, intentionally omitting hashcode implementations and null-checks to keep the code short:</p>
  
  
  
  <pre class="lang-java prettyprint-override"><code>public abstract class Vehicle {
  
      private final String color;
  
      public Vehicle(String color) {
          this.color = color;
      }
  
      public String getColor() {
          return color;
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
  
          if (!(o instanceof Vehicle)) return false;
  
          Vehicle that = (Vehicle) o;
  
          return color.equals(that.color);
      }
  
  }
  
  public class Bicycle extends Vehicle {
  
      public Bicycle(String color) {
          super(color);
      }
  
  }
  
  public class Car extends Vehicle {
  
      private final String model;
  
      public Car(String color, String model) {
          super(color);
          this.model = model;
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
  
          if (!(o instanceof Car)) return false;
  
          Car that = (Car) o;
  
          return getColor().equals(that.getColor()) &amp;&amp; model.equals(that.model);
      }
  
  }
  </code></pre>
  
  <p>When I create one instance of each class with the same color string, the symmetry of <code>equals()</code> is broken:</p>
  
  <pre class="lang-java prettyprint-override"><code>Bicycle bicycle = new Bicycle("blue");
  Car car = new Car("blue", "Mercedes");
  
  bicycle.equals(car) &lt;- true
  car.equals(bicycle) &lt;- false
  </code></pre>
  
  <p>I am unsure on how to handle this the best way. Declare <code>equals()</code> as abstract in the abstract class to enforce an implementation in the subclasses? But the same effect could be achieved by not declaring <code>equals ()</code> at all in the abstract class.</p>