both the set of data that is clustered together and the code that manipulates the data. When we
extend one class with another class, we can add data to the collection that is associated, add
or replace implementations of the methods that manipulate the data, or simply reuse the code
that was written for the class being extended.
If we take this distinction between class and interface seriously, we end up with an overarch-
ing rule for good design. Methods will be declared in an interface, along with the other meth-
ods that, taken together, form a semantic unit. Extensions of an interface will declare methods
that can refine the meaning of the original interface. The arguments and return values of these
methods will all be defined in interfaces as well.
Classes will define a set of data items that can be used to store information for the particular
implementation of the class (hidden, as will be discussed in a different chapter), and will spe-
cify a set of interfaces that declare the methods used to manipulate the state. A class will also
contain the code that is used to implement the methods declared in the interface. This code
may include additional implementation-specific “helper methods” that are not declared in the
interfaces. In this way classes provide the concrete details of a particular implementation of
some set of interfaces.
Is there ever a time when you want to declare the type of an argument or a return value to be
a class rather than an interface? Since a class is a concrete implementation of some particu-
lar set of methods, the only time you would want to do this would be if there were only one
possible way to implement those methods. There have been some times when I have believed
this of a class, but in all such cases the passage of time has proved me wrong. I can only speak
from my personal experience, but whenever I've declared a method to have an argument or a
return value that isn't of some interface type, I have later regretted it. Your mileage may vary,
but not by much. If your system is going to last, you are better off ensuring that all methods
take arguments and return values declared with interfaces.
There are rare times when you might want to declare a method as part of defining a class rather
than as part of an interface. This most often happens when you need to add a method or two to
the objects of a class that aren't really part of the core functionality of that class and really are
tied to a particular implementation. One example of this is when you want to break the imple-
mentation of an externally visible method into more manageable pieces. Another example is
debugging methods, or those that allow you (the programmer) to look at parts of the internal
state of the object. Even in these cases, you may find that you are adding the same collection
of methods to different classes, which is a sure sign that you should have declared an interface
with the methods so that you can find all of the places where the methods are used. But often
expediency will get in the way of good design. These methods are the design equivalent of
belching in public; you know that you shouldn't do it, but sometimes it is required.