Java Reference
In-Depth Information
letting an animal act, and then override it in each subclass so that we have a polymorphic
method call to let each animal act appropriately, without the need to test for the specific animal
types. This is a standard refactoring technique in situations like this, where we have subtype-
specific behavior invoked from a context that only deals with the supertype.
Let us assume that we create such a method, called
act
, and investigate the resulting source
code. Code 10.6 shows the code implementing this solution.
Code 10.6
The fully improved
solution to animal
action
// Let all animals act.
for
(Iterator<Animal> it = animals.iterator(); it.hasNext(); ) {
Animal animal = it.next();
animal.act(newAnimals);
// Remove dead animals from the simulation.
if
(! animal.isAlive()) {
it.remove();
}
}
Several observations are important at this point:
■
The variable we are using for each collection element (
animal
) is of type
Animal
. This is
legal, because all objects in the collection are foxes or rabbits and are all subtypes of Animal.
■
We assume that the specific action methods (
run
for
Rabbit
,
hunt
for
Fox
) have been renamed
act
. This is more appropriate than previously. Instead of telling each animal exactly what to do,
we are just telling it to “act,” and we leave it up to the animal itself to decide what exactly it wants
to do. This reduces coupling between
Simulator
and the individual animal subclasses.
■
Because the dynamic type of the variable determines which method is actually executed (as
discussed in Chapter 9), the fox's action method will be executed for foxes and the rabbit's
method for rabbits.
■
Because type checking is done using the static type, this code will compile only if class
Animal
has an
act
method with the right header.
The last of these points is the only remaining problem. Because we are using the statement
animal.act(newAnimals);
and the variable
animal
is of type
Animal
, this will compile only if
Animal
defines an
act
method—as we saw in Chapter 9. However, the situation here is rather different from the situ-
ation we encountered with the
display
method in Chapter 9. There, the superclass version of
display
had a useful job to do: print the fields defined in the superclass. Here, although each
particular animal has a specific set of actions to perform, we cannot describe in any detail the
actions for animals in general. The particular actions depend on the specific subtype.
Our problem is to decide how we should define
Animal
's
act
method.
The problem is a reflection of the fact that no instance of class
Animal
will ever exist. There
is no object in our simulation (or in nature) that is just an animal and not also an instance of a
Search WWH ::
Custom Search