Composition is often a better way to reuse or vary behavior because an object can delegate work to a collaborator rather than inherit a fixed parent implementation. That makes it easier to swap a compatible collaborator without changing the object that uses it. It is a rule of thumb, not a ban on inheritance: use inheritance when a type is genuinely substitutable for its parent or when a framework deliberately provides a subclass extension point.
How composition and inheritance differ
Inheritance derives one class from another. Composition makes an object work with one or more other objects it contains or references. The familiar shorthand is that inheritance models “is-a,” while composition models “has-a”—but the relationship must be valid in behavior, not just in wording.
As an Amazon Associate I earn from qualifying purchases.
For example, an illustrative notification service could inherit from a particular email sender, tying the service to that sender’s implementation. Alternatively, it could hold a sender collaborator behind an interface and delegate the delivery work. The second design expresses that the service has a way to send a message, without claiming that the service is an email sender.
Why composition can make reuse more flexible
It reduces dependence on a parent’s internal implementation
A subclass may rely on details of how its parent works, not just the parent’s public behavior. If the parent implementation changes, the child may need changes too. The authors of Design Patterns: Elements of Reusable Object-Oriented Software describe this as a limit on flexibility and reuse. NASA’s Software Engineering Handbook likewise notes that inheritance creates a dependency between child and parent classes. NASA Software Engineering Handbook, SWEREF-643.
#1 Best Overall
It allows compatible behavior to be replaced
If the containing object talks to a collaborator through a well-designed interface, another object that meets that interface can take its place. The containing object’s code need not know the collaborator’s internals. This is useful when behavior should vary at runtime—for example, when choosing among compatible strategies or service implementations.
Composition does not remove coupling altogether: the caller still depends on the collaborator’s interface and on clear delegation rules. Its benefit is that the dependency can be placed at an explicit boundary instead of binding reuse to a particular parent implementation. The Gang of Four summarize the preference this way: “Favor object composition over class inheritance.” They also write that it helps keep each class “encapsulated and focused on one task.” The book’s design-principles discussion.
Rank #2
It can keep responsibilities focused
A class that delegates a distinct responsibility can stay focused, while the collaborator handles that behavior. This can make capabilities easier to combine independently. The trade-off is that the system may contain more objects, and following what happens may require tracing several relationships and delegation steps.
When composition is a good fit
- You want to combine capabilities without claiming that one type is a subtype of another.
- You need to swap an algorithm, policy, or service implementation independently of the object that uses it.
- A subclass would inherit methods or assumptions that do not belong in its public behavior.
- You want a clearer boundary around an external service or a changeable implementation.
In each case, define the collaborator boundary around behavior the caller actually needs. An interface that is too broad or a chain of many small collaborators can make the design harder to understand rather than more flexible.
When inheritance is the better choice
The derived type honors the parent’s behavior contract
Inheritance is appropriate when the proposed child can stand in for the parent wherever clients rely on the parent’s behavior. A name that sounds like an “is-a” relationship is not enough if the child violates the expectations attached to the parent type.
A framework deliberately exposes a subclass hook
Some frameworks are designed for extension through a particular base class or override point. In that case, inheritance can be the clearest way to participate, provided the subclass follows the documented contract. Inheritance and composition are not mutually exclusive: a framework component can use inheritance to expose an extension point while composed collaborators provide its internal behavior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.A practical way to decide
- Check substitutability. Ask whether clients can use the proposed child as the parent without encountering changed or broken behavior. If not, inheritance is probably borrowing implementation rather than expressing a sound subtype.
- Identify what varies. If a capability, strategy, or service should change independently, model it as a collaborator with a focused interface.
- Inspect the dependency. With inheritance, ask whether the child relies on parent implementation details. With composition, ask whether the interface captures only the behavior the caller needs.
- Trace the wiring. Make sure it remains clear which object delegates to which collaborator and where a replacement is configured.
- Use the extension contract when one exists. If a framework explicitly expects a subclass, follow that contract rather than introducing an unrelated abstraction without a reason.
Composition can require extra object wiring and may duplicate code; inheritance can be simple and useful when the subtype relationship and extension contract are sound. The Gang of Four’s recommendation is a preference, not a universal law. The sources offer qualitative design guidance, not a measured percentage improvement in productivity, reliability, or maintenance cost.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




