// Recipe implementation of the Stack ADT. public abstract class Stacks { public static Stack empty () { return new EmptyStack(); } // Recipe implementation of the Stack ADT. static abstract class StackBase implements Stack { public abstract Stack push (E x); public abstract boolean isEmpty(); public abstract E top(); public abstract Stack pop(); public abstract int size(); } // Empty stacks. // // For purpose statements and algebraic specification, see Stack.java. static class EmptyStack extends StackBase { EmptyStack () { } public Stack push (E x) { return new Push (this, x); } public boolean isEmpty () { return true; } public E top () { String msg1 = "attempted to compute the top of an empty StackInt"; throw new RuntimeException (msg1); } public Stack pop () { return this; // FIXME: this is evil } public int size () { return 0; } } // Non-empty stacks. // // For purpose statements and algebraic specification, see Stack.java. static class Push extends StackBase { private Stack s; // the other elements of this Stack private E x; // the topmost element of this Stack Push (Stack s, E x) { this.s = s; this.x = x; } public Stack push (E x) { return new Push (this, x); } public boolean isEmpty () { return false; } public E top () { return x; } public Stack pop () { return s; } public int size () { return 1 + s.size(); } } }