class Node { Shape elem; Node next; void setElem(Shape c) { elem = c; } void setNext(Node n) { next = n; } Shape getElem() { return elem; } Node getNext() { return next; } } class Stack { Node head; void push(Shape c) { Node newHead = new Node; newHead.setElem(c); newHead.setNext(head); head = newHead; } boolean isEmpty() { return head==(Node)null; } Shape top() { return head.getElem(); } void pop() { head = head.getNext(); } } class Shape { void tell () { printString("I'm a shape"); } void tellAgain() { printString("I'm just a shape"); } } class Rectangle extends Shape { void tellAgain() { printString("I'm really a rectangle"); } } class Circle extends Shape { void tellAgain() { printString("I'm really a circle"); } } class Square extends Rectangle { void tellAgain() { printString("I'm really a square"); } } int main() { Stack stk = new Stack; Shape s = new Shape; stk.push(s); s = new Rectangle; stk.push(s); s = new Square; stk.push(s); s = new Circle; stk.push(s); while (!stk.isEmpty()) { s = stk.top(); s.tell(); s.tellAgain(); stk.pop(); } return 0; }