Datasheet

}
class Square implements Shape {
public void draw()
{
System.out.println(“Drawing square”);
}
}
class Circle implements Shape {
public void draw()
{
System.out.println(“Drawing circle”);
}
}
Now define a PaintProgram class to demonstrate bounds. If you add a drawShape method that defines
a type parameter, this won’t work:
public static <S> void drawShape(S shape)
{
shape.draw();
}
So you must add a bound to the type parameter so Java treats the shape formal type parameter as a
Shape and not an Object. By bounding the type parameter to Shape, you dictate that the object passed
in must derive directly or indirectly from
Shape. Because of this, Java knows that the object is a Shape
and thus can invoke methods that belong to Shape instead of only Object methods:
public static <S extends Shape> void drawShapeBounded(S shape)
{
shape.draw();
}
As alluded to earlier, this may make you wonder if generics really are that useful. If you have to explic-
itly state the bounds on a type parameter, you may as well just use the
Shape interface to constrain a
normal method parameter. One of the places generics really do shine is easing the use of collections, and
this is probably the main justification for adding generics to Java.
Look at implementing a
drawAllShapes method that takes a parameterized ArrayList. As expected,
you need a bound here so Java does not treat the contents of the
ArrayList as Objects:
public static <T extends Shape> void drawAllShapes(ArrayList<T> shapeList)
{
T shape;
Iterator<T> shapeIterator;
shapeIterator = shapeList.iterator();
while(shapeIterator.hasNext()) {
shape = shapeIterator.next();
shape.draw();
}
}
13
Chapter 1: Key Java Language Features and Libraries
05_777106 ch01.qxp 11/28/06 10:43 PM Page 13