🎯 Chapter Insight
Inheritance often looks elegant at first glance. It promises reuse, structure, and a clear relationship between types. But over time, deep class hierarchies can become rigid and restrictive. What once felt clean and organized may turn into a system that resists change.
Pragmatic developers are cautious with inheritance because it tightly couples behavior across layers. A decision made in a base class can ripple through subclasses in ways that are difficult to predict or undo.
The so called inheritance tax is paid later. It appears when extending behavior becomes complicated, when small changes require touching multiple levels of a hierarchy, and when unintended side effects surface far from their origin.
💡 Developer Lens
In daily engineering work, inheritance issues show up subtly.
A subclass overrides behavior in unexpected ways
A change in a base class breaks multiple derived classes
A hierarchy grows deeper as new requirements are added
Shared behavior becomes hard to isolate or refactor
Each new layer adds constraints. Instead of increasing flexibility, the hierarchy narrows your options.
Composition and delegation offer a different path. By assembling behavior from smaller focused components, you reduce coupling and gain clearer boundaries. Instead of inheriting behavior automatically, you choose which capabilities to include. This makes relationships more explicit and systems easier to evolve.
Inheritance is not inherently wrong, but it should be used carefully. When flexibility matters, composition usually provides a safer foundation.
🧭 Reflection
Examine your current system and ask yourself:
Where do inheritance chains feel fragile or restrictive?
Which parts of the hierarchy are difficult to extend or modify?
Have base class decisions limited your design choices later?
Would composition make the relationships clearer?
Would smaller, focused components reduce unintended side effects?
Clarity often improves when hierarchies shrink.
⚙️ Practical Tip
Review one inheritance relationship in your codebase this week.
Identify the behavior being shared
Consider whether it can be extracted into a separate component
Explore replacing inheritance with composition or delegation
Even flattening one level of hierarchy can improve readability and long term flexibility.
Reducing depth often increases adaptability.
🔢 #31 of 53 | The Pragmatic Programmer Series
This post is part of my 53-week series summarizing The Pragmatic Programmer, one timeless principle each week, translated into modern software practice and reflection.








