Java Reference
In-Depth Information
field to Animal and provided for it there an accessor and a mutator that were called by subclass
methods, such as incrementAge . Why didn't we move incrementAge and canBreed into
Animal , then? The reason for not moving these is that, although several of the remaining
method bodies in Fox and Rabbit contain textually identical statements, their use of class
variables with different values means that they cannot be moved directly to the superclass. In
the case of canBreed , the problem is the BREEDING_AGE variable, while breed depends on
BREEDING_PROBABILITY and MAX_LITTER_SIZE . If canBreed is moved to Animal , for
instance, then the compiler will need to have access to a value for the subtype-specific breeding
age in class Animal . It is tempting to define a BREEDING_AGE field in the Animal class and
assume that its value will be overridden by similarly named fields in the subclasses. However,
fields are handled differently from methods in Java: they cannot be overridden by subclass ver-
sions. 3 This means that a canBreed method in Animal would use a meaningless value defined
in that class rather than one that is specific to a particular subclass.
The fact that the field's value would be meaningless gives us a clue as to how we can get around
this problem and, as a result, move more of the similar methods from the subclasses to the
Remember that we defined act as abstract in Animal because having a body for the method
would be meaningless. If we access the breeding age with a method rather than a field, we can
get around the problems associated with the age-dependent properties. This approach is shown
in Code 10.8.
Code 10.8
The canBreed method
of Animal
* An animal can breed if it has reached the breeding age.
* @return true if the animal can breed
public boolean canBreed()
return age >= getBreedingAge();
* Return the breeding age of this animal.
* @return The breeding age of this animal.
abstract protected int getBreedingAge();
The canBreed method has been moved to Animal and rewritten to use the value returned
from a method call rather than the value of a class variable. For this to work, a method get-
BreedingAge must be defined in class Animal . Because we cannot specify a breeding age for
animals in general, we can again use an abstract method in the Animal class and concrete
3 This rule applies regardless of whether a field is static or not.
Search WWH ::

Custom Search