You’ve felt it. That creeping dread when you open a Java class hierarchy and see seventeen levels of inheritance, each one more brittle than the last. You wonder: who built this? And more importantly — why?
If you’ve been coding long enough, you remember the first time object orientation clicked. It felt like breathing underwater for the first time. You could model the world. A Car is a Vehicle. A Dog is an Animal. It was beautiful, intuitive, almost poetic.
Inheritance was never the point. It was the marketing brochure. The real power of OOP was always hiding in the margins — in encapsulation and message passing, the two things nobody talks about at conferences.
Here’s what happened: somewhere between Smalltalk’s elegant vision and enterprise Java’s nightmare factories, we lost the plot. We took a paradigm built on the idea of objects sending messages to each other and turned it into an exercise in taxonomic classification. We started building inheritance trees so deep they needed their own geological survey.
I saw this firsthand in a .NET codebase where a simple button component inherited from seven ancestors. Seven. To change a tooltip, you had to understand the entire chain of command. The promise was natural modeling. The reality was a fragile cathedral where touching one brick brought down the spire.
The ancient programmers among us — those who cut their teeth on 6502 assembly and lived through the Smalltalk revolution — they know. OOP is in their blood. They remember when objects were about hiding complexity behind clean interfaces, not about building elaborate family trees that collapse under their own weight.
Every deep inheritance hierarchy is a confession that someone stopped thinking about messages and started obsessing over taxonomy. It’s cargo cult architecture — building runways and hoping the planes come.
Alan Kay, the man who literally invented the term “object-oriented programming,” once said he regretted calling it that. He wished he’d called it “message-oriented programming.” Because that was the insight: objects that communicate through well-defined boundaries. Not classes that inherit from classes that inherit from classes.
Think about polymorphism for a second. Really think about it. When you send a message to an object and it responds appropriately regardless of its concrete type — that’s where the magic lives. That’s the flexibility. That’s the power. Not the fact that a Manager extends Employee extends Person extends Mammal extends OrganicLifeForm.
Encapsulation is a contract. Inheritance is a cage. The moment you reach for “extends,” ask yourself if you’re building a system or a prison.
And now we’re in the era of vibe coding — where developers whose main job is clicking “Yes” on AI-generated suggestions are producing OOP code that makes the old enterprise nightmares look tame. The cargo cult has automated itself. We’re generating inheritance hierarchies at scale, with no one stopping to ask whether the abstraction actually serves the problem.
Here’s what I want you to take away: the next time you reach for inheritance, stop. Ask yourself: can I compose instead? Can I define an interface and let objects pass messages through it? Can I hide the complexity behind a clean boundary rather than spreading it across a family tree?
The love letter to object orientation isn’t about what we’ve built with it. It’s about what we could build if we remembered what it was actually for.
The best object-oriented code you’ll ever write has no inheritance at all — just objects, talking to each other, through walls they can’t see through.
FAQ
Q: Isn't inheritance fundamental to OOP? How can you call it a lie?
A: Inheritance is a feature, not the foundation. Alan Kay, who coined the term OOP, said the core idea was message passing between encapsulated objects. Inheritance hierarchies became popular because they're easy to teach and easy to draw on whiteboards — not because they produce maintainable systems.
Q: So I should never use inheritance?
A: Not never — just rarely. Use it for genuine is-a relationships that are stable and shallow. If your hierarchy is more than two or three levels deep, you're almost certainly building a maintenance nightmare. Favor composition and interfaces in 90% of cases.
Q: Isn't this just the same old composition-over-inheritance argument?
A: Yes, but the stakes are higher now. With AI generating code at scale, the cargo cult practices around inheritance aren't just bad style — they're being amplified and reproduced automatically. The cost of getting this wrong compounds when a language model inherits your bad architecture across a million lines of generated code.