/* the main method instantiates drinkers and directs them to a newly-instantiated wall of beer. */ public class Sing99Bob { public static void main(String[] args) { ((NeedToFindBeer)(new Drinkers())).pointAtBeer(new WallOfBeer()); } } interface NeedToFindBeer { void pointAtBeer(WallOfBeer wob); } /* an instance of Drinkers, after being pointed at a wall containing beer, will periodically take one down. The singing is driven by the taking of the beer. */ class Drinkers extends Thread implements NeedToFindBeer { static final int drinkRate = 2; WallOfBeer ourBeer; public void run() { while (ourBeer.takeOne()>0) { try { Thread.sleep(drinkRate*1000); } catch (InterruptedException ignore) {} } } public void pointAtBeer(WallOfBeer wob) { ourBeer = wob; this.start(); } } interface Countable { int howMany(); } /* an instance of a WallOfBeer will maintain a count of the beer bottles. The wall has an associated Narrator who reports each time the number of bottles is changed. */ class WallOfBeer implements Countable { static final int full = 99; int count = 0; WallWatcher ww; { ww = new Narrator(); putSome(full); } void putSome(int some) { cou