/* * Bookstore list: abstracting over Object; */ import tester.*; /* +---------+ | ILoObj |<--------+ +---------+ | +---------+ | | | | | /_\ | | | +--------------+ | v v | +---------+ +--------------+ | | MTLoObj | | ConsLoObj | | +---------+ +--------------+ | +-| Object first | | | | ILoObj rest |-+ | +--------------+ v +---------------+ | Book | +---------------+ | String title | | String author | | int year | +---------------+ */ // to represent a book in a bookstore class Book{ String title; String author; int year; Book(String title, String author, int year){ this.title = title; this.author = author; this.year = year; } /* TEMPLATE: FIELDS: ... this.title ... -- String ... this.author ... -- String ... this.year ... -- int METHODS FOR FIELDS: ... this.name.equals(String) ... -- boolean ... this.author.equals(String) ... -- boolean METHODS FOR THIS CLASS: ... this.same(Book) ... -- boolean */ // is this the same book as the given book? boolean same(Book that){ return this.title.equals(that.title) && this.author.equals(that.author) && this.year == that.year; } } // to represent a list of books interface ILoObj{ // compute the total size of this list int size(); // does this list of books contain the given book? boolean contains(Object b); } // to represent an empty list of books class MtLoObj implements ILoObj{ MtLoObj(){} // compute the total size of this list public int size(){ return 0; } // does this list of books contain the given book? public boolean contains(Object b){ return false; } } // to represent a nonempty list of books class ConsLoObj implements ILoObj{ Object first; ILoObj rest; ConsLoObj(Object first, ILoObj rest){ this.first = first; this.rest = rest; } /* TEMPLATE: FIELDS: ... this.first ... -- Book ... this.rest ... -- ILoB METHODS FOR FIELDS: ... this.first.same(Book) ... -- boolean ... this.rest.size() ... -- int ... this.rest.contains(Book) ... -- boolean */ // compute the total size of this list public int size(){ return 1 + this.rest.size(); } // does this list of books contain the given book? public boolean contains(Object b){ return this.first.same(b) || this.rest.contains(b); } /* // produce a list of all books published before the given year public ILoB allBefore(int limit){ if (this.first.year < limit){ return new ConsLoB(this.first, this.rest.allBefore(limit)); } else{ return this.rest.allBefore(limit); } } */ } // Examples and tests for books and lists of books class Examples{ Examples(){} Book oms = new Book("Old Man and the Sea", "Hemingway", 1952); Book eos = new Book("Elements of Style", "EBW", 1927); Book htdp = new Book("HtDP", "MF", 2001); Book ll = new Book("Little Lisper", "MF", 1995); ILoObj mtlob = new MtLoObj(); ILoObj blist2 = new ConsLoObj(this.oms, new ConsLoObj(this.eos, this.mtlob)); ILoObj blist3 = new ConsLoObj(this.htdp, this.blist2); // test the method same in the classes that implement ILoB boolean testSame(Tester t){ return t.checkExpect( this.oms.same(new Book("Old Man and the Sea", "Hemingway", 1952)), true) && t.checkExpect(this.eos.same(this.htdp), false) && t.checkExpect(this.htdp.same(this.ll), false) ;} // test the method size in the classes that implement ILoB boolean testSize(Tester t){ return t.checkExpect(this.mtlob.size(), 0) && t.checkExpect(this.blist2.size(), 2) && t.checkExpect(this.blist3.size(), 3);} // test the method contains in the classes that implement ILoB boolean testContains(Tester t){ return t.checkExpect(this.mtlob.contains(this.htdp), false) && t.checkExpect(this.blist2.contains(this.htdp), false) && t.checkExpect(this.blist3.contains(this.htdp), true);} }