| 
 
 |   
 | 
class Dictionary
  void add(Key k, Value v) { }
  Value find(Key k) { }
  void delete(Key k) { }
class Dictionary
  void add(Key k, Value v) { }
abstract void add(Key k, Value v); abstract void delete(Key k); abstract Value find(Key k);
Dictionary d = new Dictionary();
d.find("hello") // ???
Dictionary d = new HashTableDictionary();
abstract.
    abstract class Dictionary abstract void add(Key k, Value v); // and so on.
Dictionary d = new HashTableDictionary();
HashTableDictionary d = new HashTableDictionary();
HashTableDictionary-specific methods is even worse.
    
class Blob extends Object { ... }
class Spot { ... }
class Drop extends Spot { ... }

class Stack 
  void push(Object o) { ... }
  Object pop() { ... }

stack.push("blah"); use(stack);
stack.push(new Blob()); use(stack);
stack.push(stack); use(stack);
use() 
look like?
void use(Stack s) ??? e = (???) s.pop(); // and so on.
public boolean equals(Object o) public int hashCode() public String toString() protected Object clone()


Object.equals()Object.equals() implements identity:
public boolean equals(Object o) return this == o
StringBuffer 
  sb1 = new StringBuffer("woof"),
  sb2 = new StringBuffer("woof");
if (sb1.equals(sb2))
  // Identically false, 
  // but usually should be true.
equals() implementation should satisfy the equality
  contract.
    
equals() implementations is quick way
  to estimate development quality.
  
equals() should be 
    x.equals(x) is always true.
    x.equals(y) then y.equals(x).
    x.equals(y) and y.equals(z), then x.equals(z).
    x.equals(null) is always false.
    x and y don’t change, then x.equals(y)
    doesn’t either.
    
public boolean
equals(Object o)
  if this == o     // reflexive
    return true
  if o == null     // null rejecting
    return false;
  if getClass() != o.getClass()
    return false
  final Card c = (Card) o
  
  return 
    c.suit == suit && 
    c.rank == rank
if getClass() != o.getClass() return false
can be too strong and may need to be weakened to
if !(o instanceof class) return false
class Point int x, y
Point.equals() mean?
    
class ColoredPoint extends Point Color color
ColoredPoint.equals() mean?
    Point.equals()? 
    
class coloredPoint
  // Standard method lookup
  // equals() could be dropped.
  public boolean 
  equals(Object o)
    return super.equals(o)
class coloredPoint
  public boolean 
  equals(Object o)
    return super.equals(o) && 
      color.equals(
        ((coloredPoint) o).color)
cp1.equals(p1) and p1.equals(cp1) fail because
getClass() == o.getClass()
fails.
coloredPoint(1, 2, Color.RED)
  equalpoint(1, 2)?
  
cp1.equals(p1) and p1.equals(cp1) fail because
getClass() == o.getClass()
fails.
coloredPoint(1, 2, Color.RED)
  equalpoint(1, 2)?
  
Object.hashCode()o.hashCode() returns an int hash code for o.
  hashCode() contract:
    x.equals(y), then x.hashCode() == y.hashCode().
    
equals() requires overriding hashCode().
    hashCode() contract.
    
hashCode() ExampleObject.hashCode() returns a hash code based on instance address.
  Object.hashCode() doesn’t obey the hashCode() property
  with respect to Card.equals(). (Why?)
class Card
  private int rank;  // 1 to 13
  private char suit; // c, d, h, or s
  int hashCode()
    return rank + suit;
  
Object.toString()String toString() returns a printable
  representation of this.
  toString() for significant classes.
employeeName.toString()→
"EmployeeName@1cd2e5f", not so good.
employeeName.toString()→
"George Leroy Tirebiter", better.