Design recipes for methods for unions of classes. Design recipes for method for classes that represent self-referential data. Abstracting common data and common behavior in unions of classes.
The only data we need is the list of books.
// PURPOSE AND CONTRACT: // count the number of books in this list abstract int count();
We develop the methods in the two classes concurrently, starting with examples.
Book b1 = new Book("HtDP", "Matthias", 60, 2001);
Book b2 = new Book("Beach Music", "Conroy", 20, 1996);
Book b3 = new Book("3 Com", "Remarque", 15, 1937);
ALoB mtlob = new MtLoB();
ALoB lob1 = new ConsLoB(b1, mtlob);
ALoB lob2 = new ConsLoB(b2, lob1);
ALoB lob3 = new ConsLoB(b3, lob2);
...
mtlob.count() -- expected: 0
lob1.count() -- expected: 1
lob2.count() -- expected: 2
lob3.count() -- expected: 3
There is a separate template for each of the two subclasses.
/* TEMPLATE for the MtLoB class:
int count() {
... } */
/* TEMPLATE for the ConsLoB class:
int count() {
... this.fst ...
... this.rst.count() ... } */
Again, we have two different methods, one for each class.
// PROGRAM for the class MtLoB:
int count() {
return 0; }
// PROGRAM for the class ConsLoB:
int count() {
return 1 + this.rst.count(); }
mtlob.count() == 0 lob1.count() == 1 lob2.count() == 2 lob3.count() == 3