Practice with Composite and Interpreter Patterns
Another Composite Example Computing with Lists
An IntList is either:
Empty(), the empty list, or
NonEmpty(first,rest), a non-empty list, where first is an int and rest is an IntList.
Some examples include:
Empty()
NonEmpty(7,Empty())
NonEmpty(12, NonEmpty(17, Empty()))

IntList
import java.util.NoSuchElementException;
abstract class IntList {
  abstract int getFirst();
  abstract IntList getRest();
}
class Empty extends IntList {
  int getFirst() {
    throw new
      NoSuchElementException("getFirst applied to Empty()");
  }
  int getRest() {
    throw new
      NoSuchElementException("getRest applied to Empty()");
  }
  public String toString() { return "Empty()"; }
}
class NonEmpty extends IntList {
  int first;
  IntList rest;
  int getFirst() { return first; );
  IntList getRest() { return rest; }
  public String toString() { return "NonEmpty(" + first + ", " + rest + ")"; }
}

Remarks on IntList
The operations getFirst() and getRest() are included in the abstract class IntList because they are useful operations for clients of  IntList.
Invoking getFirst() or getRest() on the Empty list is a run-time error, which we implement by throwing an exception.  The Java throw  construct takes an object of type Exception (which is a built-in class).  In the absence of a catch handler attached to a method on the call stack, throwing an exception aborts the computation and prints the String message embedded in the exception.

Finger Exercise
Open the class IntList.java in DrJava, compile it, and try evaluating
new Empty().getFirst()
il1 = new NonEmpty(17, new Empty())
il1
Il1.getRest().getFirst()

The Singleton Pattern
Each execution of the expression
new Empty()
creates a new object.  In principle, there is only one empty list, just like there is only one number 0.  Hence, we would like to represent the empty list by a single library.
The singleton pattern is the mechanism that we use to create a unique instance of a class.  This pattern consists of two chunks of code:
a static final field in the class that holds the single instance of the class
a private attribute on the class constructor, so no client can create another instance of the class.

Singleton IntList
import java.util.NoSuchElementException;
abstract class IntList {
  abstract int getFirst();
  abstract IntList getRest();
}
class Empty extends IntList {
  static final Empty ONLY = new Empty();
  private Empty() {}
  int getFirst() {
    throw new
      NoSuchElementException("getFirst applied to Empty()");
  }
  int getRest() {
    throw new
      NoSuchElementException("getRest applied to Empty()");
  }
  public String toString() { return "Empty()"; }
}
class NonEmpty extends IntList {
  int first;
  IntList rest;
  int getFirst() { return first; );
  IntList getRest() { return rest; }
  public String toString() { return "NonEmpty(" + first + ", " + rest + ")"; }
}