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
superclass.
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