Favor composition over inheritance when a has-a relationship makes behavior more flexible than an is-a hierarchy. Composition aggregates behavior objects and avoids hardcoding every behavior into subclasses. section 7.3 section 7.6
Composition improves a design by providing:
- Runtime flexibility: assign behaviors during construction and modify them later. section 7.3
- Code sharing: reuse behavior classes instead of duplicating subclass implementations. section 7.3
- Loose coupling and encapsulation: toys need not know how play and sound behaviors are implemented. section 7.3
- Reduced complexity: simplify class hierarchies without requiring multiple inheritance. section 7.3
Refactoring toy behaviors
A subclass-based toy design hardcodes each toy’s play and sound behavior, causing duplication and change leaks. A composed Toy instead receives PlayAction and Sound objects, delegates play() and sound(), and can change a train’s sound from ChooChoo to Engine at run time. section 7.3
Figure 7.4 Each Toy subclass has an is-a relationship to the Toy superclass. The Toy superclass has has-a relationships to the PlayAction and Sound behaviors, which allows the Toy subclasses to access and share play action and sound behaviors. This design is more flexible and has loose coupling between the toys and their play action and sound behaviors. The toy behaviors are no longer hardcoded in the source code but can be specified whenever a toy object is created at run time. A toy’s behaviors can also be modified at run time by calling the setter functions set_play() and set_sound().
The relationship diagram shows toys retaining inheritance for their identity while composing replaceable play and sound behaviors. section 7.3

