Attributed, so the class must implement all the interface's methods. AttributedImpl implements the
methods using a HashMap, described in "HashMap" on page 590. Later, this implementation is used to
implement the Attributed interface for a specific set of objects to which you would want to add attributes.
First, here is the AttributedImpl class:
import java.util.*;
class AttributedImpl implements Attributed, Iterable
protected Map<String, Attr> attrTable =
new HashMap<String, Attr>();
public void add(Attr newAttr) {
attrTable.put(newAttr.getName(), newAttr);
}
public Attr find(String name) {
return attrTable.get(name);
}
public Attr remove(String name) {
return attrTable.remove(name);
}
public Iterator
return attrTable.values().iterator();
}
public Iterator
return attrs();
}
}
The initializer for attrTable creates a HashMap object to hold attributes. This HashMap object does
most of the actual work. The HashMap class uses the key object's hashCode method to hash any object it is
given as a key. No explicit hash method is needed since String already provides a good hashCode
implementation.
When a new attribute is added, the Attr object is stored in the hash map under its name, and then you can
easily use the hash map to find and remove attributes by name. The attrs method returns the Iterator
for the hash map's values, giving access to all the attributes of the current object.
We chose to make this implementation of Attributed also implement Iterable
attributes are the only things an AttributedImpl contains. To do this, we had to define the iterator
method to return the same value as the attrs method.
4.4.2. Using an Implementation
You can use an implementing class like AttributedImpl by simply extending the class. This is the
simplest tool when it is available because all the methods and their implementations are inherited. But if you
need to support more than one interface or extend a different class, you must use a different approach. The
most common approach is to create an object of an implementing class and forward all the methods of the
interface to that object, returning any valuesthis is often called composition.
In composition and forwarding, each method in the class that is inherited from the interface invokes the
implementation from another object and returns the result. Here is an implementation of the Attributed
interface that uses an AttributedImpl object to build an attributed version of our previously defined