their code to a specific implementation because a change in requirements for the next
significant amounts of code, which wastes time and slows development.
For example, the main() method following Listing 2-36 creates an array of objects
fromclassesthatsubclassthe Shape class,andtheniteratesovertheseobjects,calling
eachobject's draw() method.Theonlyobjects thatcanbedrawnarethosethatsub-
class Shape .
a drawing capability to each class that draws that component's symbol.
Youmightconsiderspecifying Shape asthesuperclassoftheelectroniccomponent
class hierarchy. However, electronic components are not shapes (although they have
shapes)soitmakesnosensetoplacetheseclassesinaclasshierarchyrootedin Shape .
However,youcanmakeeachcomponentclassimplementthe Drawable interface,
which lets you add expressions that instantiate these classes to the drawables array
inthe main() methodappearingpriorto Listing2-44 (soyoucandrawtheirsymbols).
This is legal because these instances are drawables.
For now, consider a simple example that consists of the Collections Framework's
java.util.List interface, and its java.util.ArrayList and
inflexible code based on the ArrayList class:
ArrayList<String> arrayList = new ArrayList<String>();
void dump(ArrayList<String> arrayList)
// suitable code to dump out the arrayList
This example uses the generics-based parameterized type language feature (which I
will discuss in Chapter 3 ) to identify the kind of objects stored in an ArrayList in-
stance. In this example, String objects are stored.