Prefer assembling behavior by holding references to objects that provide it ('has-a') over extending classes to inherit it ('is-a'). Composition avoids the tight coupling, fragile hierarchies, and combinatorial explosion of subclasses that inheritance produces when behavior varies across multiple independent dimensions.
Examples:
- A car catalog needs cars and trucks, each in electric or gas form, each with manual or autopilot controls. Inheritance requires 2 × 2 × 2 = 8 subclasses. With composition, a single
Vehicleclass holds aEnginefield and aNavigationfield; swapping strategies requires no new subclass — only new implementations of the relevant interface.