Java Reference
In-Depth Information
Cat cats[] = { new Cat(), new Cat(), new Cat() };
for (int i = 0; i < cats.length; i++)
cats[i].meow();
System.out.print(Dog.getCount() + " woofs and ");
System.out.println(Cat.getCount() + " meows");
}
}
Solution 47: Well, Dog My Cats!
We have two dogs woofing and three cats meowing— a ruckus, to be sure— so the program should
print
2 woofs and 3 meows
, no? No: It prints
5 woofs and 5 meows
. Where is all the extra noise
coming from, and what can we do to stop it?
The sum of the number of woofs and meows printed by the program is 10, fully twice what it
should be. The problem is that
Dog
and
Cat
inherit the
count
field from a common superclass, and
count
is a static field.
A single copy of each static field is shared among its declaring class and
all subclasses
, so
Dog
and
Cat
use the same
count
field. Each call to
woof
or
meow
increments this
field, so it is incremented five times. The program reads it twice, by calling
Dog.getCount
and
Cat.getCount
. In each case, 5 is returned and printed.
We cannot fix the problem by making
count
an instance field. That would create one counter per
pet rather than one counter per kind of pet. To fix the program, we must correct a fundamental
design error.
When designing one class to build on the behavior of another, you have two options:
inheritance
, in
which one class extends the other; or
composition
, in which one class contains an instance of the
other. Choose based on whether each instance of one class
is
an instance of the other class or
has
an
instance of the other. In the first case, use inheritance; in the second, use composition.
When in
doubt, favor composition over inheritance
[EJ Item 14].
Neither a dog nor a cat
is
a kind of counter, so it was wrong to use inheritance. Instead of extending
Counter
,
Dog
and
Cat
should each have a counter field. One counter is required for each kind of
pet, rather than for each individual pet, so these fields must be static. We needn't bother with a
Counter
class; an
int
will do fine. Here is the redesigned program, which prints
2 woofs, 3 meows
as expected:
class Dog {
private static int woofCounter;
Search WWH ::
Custom Search