
class Card {
  public boolean sameRank(Card c) { ... }
  public boolean sameSuit(Card c) { ... }
  public void makeFaceUp() { ... }
  }
class PeggingHand {
  public int pairPoints() { ... }
  public int rankPoints() { ... }
  }
class CribHand {
  public int pairPoints() { ... }
  public int rankPoints() { ... }
  public int rightJackPoints() { ... }
  }
CribHand satisfies PeggingHand’s protocol.
    PeggingHand does not satisfy CribHand’s protocol.
    
class Dictionary 
  void add(Key k, Value v) { ... }
  Value find(Key k) { ... }
  void delete(Key k) { ... }
class LinkedListDictionary 
  void add(Key k, Value v) { ... }
  Value find(Key k) { ... }
  void delete(Key k) { ... }
class HashTableListDictionary 
  void add(Key k, Value v) { ... }
  Value find(Key k) { ... }
  void delete(Key k) { ... }
  
A inherits from B A IS-A B A satisfies B’s protocol 
| 
 
 | 
 
 | 
extends class modifier signals inheritance:
class Child extends Parent { ...  }
class Dictionary {
  void add(Key k, Value v) { ... }
  Value find(Key k) { ... }
  void delete(Key k) { ... }
  }
class LinkedListDictionary
extends Dictionary {
  }
class Blob { ... }
class Spot extends Blob { ... }
class Drop extends Blob { ... }
| 
 
 | 
 
 | 
class Blob { ... }
class Spot extends Blob { ... }

classInstance instanceof Class
  returns true if classInstance’s type (that is, class) is an descendant
  of Class and false otherwise.
  
class Blob { void moo() { ... } }
class Spot 
extends Blob { void moo() { ... } }
class Drop 
extends Spot { void moo() { ... } }consider
Blob b = new Drop(); b.moo();
    Which version of moo() gets called?
  
class Blob
  void moo(int) { ... }
class Spot
extends Blob
  void moo(double) { ... }
| 
 
 | Blob b = new Spot(); b.moo(1); 
 | 
super keyword to control lookup.
  super.method(args) call the parent’s
  method.
    
this.method(args) calls
  method in the instance’s class.
  
java.lang.String is a final class. 
    
class Set {
  // blah blah blah 
  void add(Object element) { ... }
  void add(Set set) { ... }
  // blah blah blah
  }
class CountingSet extends Set
  private int count = 0
  void add(Object element)
    count++
    super.add(element) 
  void add(Set set)
    count += set.size()
    super.add(set)
  int getCount()
    return count 
CountingSet cs1 = new CountingSet()
cs1.add("Moe")
cs1.add("Manny")
cs1.add("Jack")
CountingSet cs2 = new CountingSet()
cs2.add(cs1)
System.out.printlin(
  "Add count: " + cs2.getCount())
Add count: 6 when run.  Why?
    
Set.add(Set) is implemented as
void add(Set set) 
  for (Object e: set.elements)
    /* this. */add(e)

See the code.