Both inheritance and composition allow
you to create a new type from existing types, and both embed subobjects of the
existing types inside the new type. Typically, however, you use composition to
reuse existing types as part of the underlying implementation of the new type
and inheritance when you want to force the new type to be the same type as the
base class (type equivalence guarantees interface equivalence). Since the
derived class has the base-class interface, it can be upcast to the base,
which is critical for polymorphism as you’ll see in Chapter
15.
Although code reuse through composition
and inheritance is very helpful for rapid project development, you’ll
generally want to redesign your class hierarchy before allowing other
programmers to become dependent on it. Your goal is a hierarchy in which each
class has a specific use and is neither too big (encompassing so much
functionality that it’s unwieldy to reuse) nor annoyingly small (you
can’t use it by itself or without adding
functionality).