package examples; import java.util.*; /** * CS401 Exmaple 31 * * An example showing the use of bounded wildcards. This examples makes use of * the Animal, Person, Bird, Ostrich, Fish, and Shark classes defined in example * ex23.java. * * @author PJ Dillon */ public class ex31 { public static void main(String[] args) { /* * We create a Collection of Fish, to which we can then add any instance of * a class that extends Fish, i.e. Shark. */ Collection fish = new LinkedList(); fish.add(new Shark("Jaws", Fish.WaterType.saltWater)); fish.add(new Fish("Nemo", Fish.WaterType.freshWater)); fish.add(new Shark("Lenny", Fish.WaterType.saltWater)); fish.add(new Fish("Oscar", Fish.WaterType.saltWater)); //Print the fish out System.out.println("Fish:"); printAnimals(fish); /* * We do the same for a Collection of Person. We can print them using the * same method as we did for fish. */ Collection simpsons = new LinkedList(); simpsons.add(new Person("Marge")); simpsons.add(new Person("Homer")); simpsons.add(new Person("Bart")); simpsons.add(new Person("Lisa")); simpsons.add(new Person("Magie")); System.out.println("The Simpsons:"); printAnimals(simpsons); /* * One more time with Bird */ Collection bird = new LinkedList(); bird.add(new Bird("Tweety")); bird.add(new Ostrich("Big")); System.out.println("Birds:"); printAnimals(bird); } /** * prints each of a Collection of Animals. If we declared the method to accept * only a Collection of Animal, it would then be unable to accept the * Collections of Fish, Person, and Bird created in main above. Since this * method needs to call the characteristics() and move() methods of the Animal * class, we can't use just a simple wildcard. Thus, we use the bounded * wildcard of '? extends Animal', which declares that this method can accept * a Collection of any class that is a subtype of the Animal class (Fish, * Person, and Bird are all subtypes). The compiler can then ensure that any * Collection only store elements that are instances of Animal, allowing us to * then treat each object in the Collection like an Animal object and access * the characteristics() and move() methods of that class. * * @param c Collection to print */ public static void printAnimals(Collection c) { for(Iterator i = c.iterator(); i.hasNext();) { Animal a = i.next(); System.out.println(a); a.characteristics(); a.move(); if(a instanceof Fish) { System.out.println(((Fish) a).getWaterType() + " is fun!"); } System.out.println(); } /* * The flexibility provided by the bounded wildcard is still subject to some * limitations; most notably, we are unable to make additions to the * Collections because we can't be sure what the actual type the collection * stores when it's passed. Uncomment the line below to see the error. Since * the Collection could be a collection of Bird or Fish, we can't add a * Person to it. */ //c.add(new Person("Hector")); /* * We can still remove objects from the Collection since this is safe. The * remove methods finds any objects in the Collection where the equals() * returns true with the object passed in here. Since our Animal subtype * classes do not implement a well defined equals() method, this will never * remove any objects. */ c.remove(new Person("Marge")); } }