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 reuse the
interface as well as the implementation. If 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 the next
chapter.
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 where 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). Your finished classes should themselves be easily reused.