abstract class ListOfString { abstract int length(); abstract boolean gotMilk(); boolean notMilk() { return !this.gotMilk(); } abstract ListOfString sour(); } class EmptyListOfString extends ListOfString { EmptyListOfString() { } int length() { return 0; } boolean gotMilk() { return false; } ListOfString sour() { return new EmptyListOfString(); } } class ConsListOfString extends ListOfString { String first; ListOfString rest; ConsListOfString(String first, ListOfString rest) { this.first = first; this.rest = rest; } int length() { return 1 + this.rest.length(); } boolean gotMilk() { return (this.first.equals("milk") || this.rest.gotMilk()); } ListOfString sour() { if (this.first.equals("milk")) return new ConsListOfString("yogurt", this.rest.sour()); else return new ConsListOfString(this.first, this.rest.sour()); } }