//--- File: Animal.java interface Animal { // return the name of this animal public String getName(); } // --- File: Cow.java public class Cow implements Animal { public String getName() { return "I'm a cow."; } } // --- File: Zoo.java import java.util.ArrayList; public class Zoo { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(new Cow()); list.add(new Cow()); printNames(list); } public static void printNames(ArrayList zoo) { for(Animal a : zoo) { a.getName(); } } /* //If instead of the above, we changed the parameter type of printNames to public static void printNames(ArrayList zoo) { //then the call to printNames(list); //would not work because ArrayList NOT is-a ArrayList even though Cow is-a Animal. */ } // --- File: SortedCollection.java // Therefore, if you do: interface SortedCollection > {} // ...this works, but is too restrictive. It requires that E directly // implement Comparable, but that’s not // the only way two E objects can be Comparable. // Solution: interface SortedCollectionBetter > {} // This means that any superclass of E should extend Comparable