Inheritance Is a Procedural Technique for Code Reuse

We all know that
inheritance
is bad and that
composition over inheritance
is a
good idea,
but do we really understand why?
In most all articles
I’ve found
addressing this subject, authors have said that inheritance may be harmful
to your code, so it’s better not to use it. This “better” part is what bothers me;
does it mean that sometimes inheritance makes sense?
I interviewed David West
(the author of Object Thinking, my favorite book about OOP)
a few weeks ago, and he said that inheritance should not exist in
object-oriented programming at all (full video).
Maybe Dr. West is right and we should totally forget extends keyword in Java,
for example.

I think we should. And I think I know the reason why.

It’s not because we introduce unnecessary coupling, as Allen Holub said in his
Why extends is evil article.
He was definitely right, but I believe it’s not the root cause of the problem.

“Inherit,” as an English verb, has a number of meanings.
This one
is what inheritance inventors in Simula had in mind, I guess:
“Derive (a quality, characteristic, or predisposition) genetically from one’s parents or ancestors.”

Deriving a characteristic from another object is a great idea, and it’s called
subtyping.
It perfectly fits into OOP and actually enables
polymorphism:
An object of class Article inherits all characteristics of objects in class Manuscript
and adds its own. For example, it inherits an ability to print itself
and adds an ability to submit itself to a conference:

This is subtyping, and it’s a perfect technique; whenever a
manuscript is required, we can provide an article and nobody will
notice anything, because type Article is a subtype of type Manuscript
(Liskov substitution principle).

But what does copying methods and attributes from a parent class to a child
one have to do with “deriving characteristics?” Implementation inheritance
is exactly that—copying—and it has nothing to do with the meaning
of the word “inherit” I quoted above.

Implementation inheritance is much closer to a different
meaning:
“Receive (money, property, or a title) as an heir at the death of the previous holder.”
Who is dead, you ask? An object is dead if it allows other objects to
inherit its encapsulated code and data. This is implementation
inheritance:

Class Articlecopies method print() and attribute body
from class Manuscript, as if it’s not a
living organism, but rather a dead
one from which we can inherit its parts, “money, properties, or a title.”

Implementation inheritance was created as a mechanism for
code reuse,
and it doesn’t fit into OOP at all. Yes, it may look convenient in the
beginning, but it is absolutely wrong in terms of object thinking.
Just like getters and setters,
implementation inheritance turns
objects into containers with data and procedures. Of course, it’s
convenient to copy some of those data and procedures to a new object
in order to avoid code duplication. But this is not what objects are about. They
are not dead; they are alive!

Don’t kill them with inheritance :)

Thus, I think inheritance is bad because it is a procedural technique for code reuse.
It comes as no surprise that it introduces all the problems people have been talking about for years.
Because it is procedural!
That’s why it doesn’t fit into object-oriented programming.

By the way, we discussed
this problem in our
Gitter chat (it’s dead already)
a week ago, and that’s when it became obvious to me what exactly is
wrong with inheritance. Take a look at our discussion there.