// generics/Fill41.java // TIJ4 Chapter Generics, Exercise 41, page 737 // Modify Fill2.java to use the classes in typeinfo.pets instead // of the Coffee classes. // Using adapters to simulate latent typing. // {main: Fill41Test} import typeinfo.pets.*; import java.util.*; import net.mindview.util.*; import static net.mindview.util.Print.*; interface Addable { void add(T t); } public class Fill41 { // Classtoken version: public static void fill(Addable addable, Class classToken, int size) { for(int i = 0; i < size; i++) try { addable.add(classToken.newInstance()); } catch(Exception e) { throw new RuntimeException(e); } } // Generator version: public static void fill(Addable addable, Generator generator, int size) { for(int i = 0; i < size; i++) addable.add(generator.next()); } } // To adapt a base type, your must use composition. // Make any Collection Addable using composition: class AddableCollectionAdapter implements Addable { private Collection c; public AddableCollectionAdapter(Collection c) { this.c = c; } public void add(T item) { c.add(item); } } // A helper to capture the type automatically: class Adapter { public static Addable collectionAdapter(Collection c) { return new AddableCollectionAdapter(c); } } // To adapt a specific type, you can use inheritance. // Make a SimpleQueue Addable using inheritance: class AddableSimpleQueue extends SimpleQueue implements Addable { public void add(T item) { super.add(item); } } class Fill41Test { public static void main(String[] args) { // Adapt a collection: List pets = new ArrayList(); Fill41.fill( new AddableCollectionAdapter(pets), Pet.class, 3); // Helper method captures the type: Fill41.fill(Adapter.collectionAdapter(pets), Manx.class, 2); for(Pet p : pets) print(p); print("---------------"); // Use an adapted class: AddableSimpleQueue petQueue = new AddableSimpleQueue(); Fill41.fill(petQueue, Pug.class, 4); Fill41.fill(petQueue, Gerbil.class, 1); for(Pet p : petQueue) print(p); } }