/*********************************************** * CS2510 Spring 2011 * Lecture #16 * Type Parameters, Generics, adn Function-Classes ***********************************************/ import tester.*; // Represents a Puppy (Awww....) class Puppy{ String name; String eyecolor; boolean boy; Puppy(String name, String eyecolor, boolean boy) { this.name = name; this.eyecolor = eyecolor; this.boy = boy; } } // Represents something that can be "traversed" that // contains Xs interface Traverse{ // Is this thing empty? public boolean emptyHuh(); // Get the first of this thing public X getFirst(); // Get the rest of this thing public Traverse getRest(); } // Represents a List of Xs interface ILo extends Traverse{ // Compute the length of this List of X public int length(); // Transform all the elements of this List of X into // a new List of Y public ILo transformAll(IMap mapper); } // Represents an empty List of Xs class MtLo implements ILo{ MtLo(){} // Compute the length of this List of X public int length(){ return 0; } // Transform all the elements of this List of X into // a new List of Y public ILo transformAll(IMap mapper){ return new MtLo(); } // Is this list empty? public boolean emptyHuh(){ return true; } // Get the first of this List public X getFirst(){ throw new RuntimeException("No First Yahoo"); } // Get the rest of this List // Note: it's safe to have the return type of ILo // even though it overrides the Traverse method public ILo getRest(){ throw new RuntimeException("No Rest Yahoo"); } } // Represents a nonempty List of Xs class ConsLo implements ILo{ X first; ILo rest; ConsLo(X first, ILo rest){ this.first = first; this.rest = rest; } /** Template * Fields: * ... this.first ... -- X * ... this.rest ... -- ILo * * Methods: * ... this.length() ... -- int * ... this.transformAll(IMap) -- ILo * * Methods for Fields: * ... this.rest.length()... -- int * ... this.rest.transformAll(IMap) -- ILo */ // Calculate the length of this List of Xs public int length(){ return 1 + this.rest.length(); } // Transform all the elements of this List of X into // a new List of Y public ILo transformAll(IMap mapper){ // Template // ... mapper.transform(X) -- Y // ... this.first -- X // ... this.rest -- ILo return new ConsLo(mapper.transform(this.first), this.rest.transformAll(mapper)); } // Is this List empty? public boolean emptyHuh(){ return false; } // Get the first of this List public X getFirst(){ return this.first; } // Get the rest of this List // Note: Again, it's safe to have the return type of ILo // even though it overrides the Traverse method public ILo getRest(){ return this.rest; } } // A Class to represent various algorithms (functions/methods) class Algo{ // Compute the length of the given Traverse of X public int length(Traverse lox){ if(lox.emptyHuh()){ return 0; }else{ return 1 + this.length(lox.getRest()); } } } // Represents a method that transforms Xs into Ys interface IMap{ // Transforms the given X into a Y public Y transform(X x); } // Represents the function from Puppys to their names // [Puppy -> String] class PuppyName implements IMap{ // Get the Puppy's name public String transform(Puppy p){ return p.name; } } // Examples and Tests class LectureExamples{ IMap pup = new PuppyName(); Algo algo = new Algo(); ILo mtS = new MtLo(); ILo mtP = new MtLo(); Puppy fred = new Puppy("Fred", "baby-blue", false); Puppy java = new Puppy("Java", "red", true); ILo gavins_dogs = new ConsLo(this.fred, new ConsLo(this.java, this.mtP)); ILo gavins_strings = new ConsLo("Fred", new ConsLo("Java", this.mtS)); // Boxing/unboxing examples int mine = new Integer(5) + 7; Integer yours = 5 * 3; ILo my_ints = new ConsLo(7, new MtLo()); // Tests for our methods... void testAll(Tester t){ t.checkExpect(this.gavins_dogs.transformAll(pup), this.gavins_strings); t.checkExpect(this.gavins_dogs.length(), 2); t.checkExpect(this.gavins_dogs.transformAll(pup).length(), 2); t.checkExpect(this.algo.length(this.gavins_dogs.transformAll(pup)), 2); t.checkExpect(this.algo.length(this.gavins_dogs), 2); t.checkExpect(this.algo.length(this.gavins_strings), 2); } }