An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

The Pain of Inheritance

April 19, 2004 ·

When programmers first learn OOP, they tend to overuse inheritance - they see it everywhere and often end up with deeply-nested inheritance trees. This is a Bad Thing. In the real world, inheritance is actually fairly rare because inheritance represents the "is-a" relationship and most real world relationships between entities are more "has-a" than "is-a". Some languages make inheritance more appealing than others. C++ forces you to explicitly declare methods as virtual in order to create the polymorphic behavior associated with inheritance but, on the other hand, encourages you to inherit left, right and center by supporting multiple inheritance. Java proudly eschews that technique but makes all methods virtual by default thus encouraging overuse of inheritance in a different way. Ted Neward mentioned Smalltalk recently (see my earlier blog entry) as a context where inheritance is the hammer for all problems, and in two further posts, he takes Cedric and Bo to task for defending the inheritable-by-default position. Having programmed extensively in both C++ and Java (as well as some Smalltalk), I think I'd side with Ted on this issue because it is harder to write good base classes than it is to write good leaf classes and, in my experience, most classes are not base classes - so it's better to protect the majority and inconvenience the minority.

Tags: programming

12 responses

  • 1 JesterXL // Sep 8, 2004 at 5:04 PM

    "The needs of the many outweigh the needs of the few." -- Spock<br /><br />ComPoSitioN baby!!!!
  • 2 Sam // Sep 8, 2004 at 5:04 PM

    When I first wrote our Flash MX component set I used inheritence extensively to reuse code and came up with a very deep structure. Everything worked great until I had to create one component that needed to borrow functionality from a few classes at the same level in the hierarchy We never implemented this component in the MX version. <br /><br />When we ported to v2 framework I moved a lot of functionality to composed helper objects that were easily reusable and ended up with a much more flexible component set. Your blog entry is about two years too late for me--I learned the hard way. :-)
  • 3 Obelix // Sep 8, 2004 at 5:04 PM

    I see the point that you are making that, inheritance should be avoided because of the difficulty associated with such a structure. But to say that in the *real world* inheritence is a a rare thing is innacurate.<br /><br />There exist many relationshps true, and composition is one of them. A car has an engine. Yet inheritance is all around us, a person has a heart, but that heart is an organ. A person for that matter is a mammal (albeit a smart one) which is an animal.<br /><br />My 2 cents.
  • 4 seancorfield // Sep 8, 2004 at 5:04 PM

    Yes, heart "is-a" organ but what does that buy you in the real world? Is there any polymorphic behavior associated with "organ"? No. The same applies to person "is-a" mammal to some extent. Yes, there is some generic behavior associated with "mammal" that applies to "person" but it's rarely useful to take advantage of that behavior (you don't have "collections" of "mammals" and make them all do the same thing - yet we see endless examples of "animal.talk()" in OOP literature).<br /><br />My point is that inheritance as shown in OOP is more an aspect of the model than an aspect of the real world.
  • 5 Obelix // Sep 8, 2004 at 5:04 PM

    You are taking my argument a little too literative.<br /><br />Lets take muscles for example.<br />1. a person has a bicep which is a muscle<br />2. a person has a tricept which is a muscle<br /><br />both muscles are plymorphic in that they both have the same sort of methods, as in pull and push. Now i could say muscle pull, and my arm would move.<br /><br />Same with heart. Yes its an organ but its a specific subclass of an organ. For argument sake i will say that heart is part of the pump family of organs. All organs who belong to that family perform the same general operation. They pump a liquid. So we could have heart.pump( blood ) while some other magical organ could have magicalOrgan.pump( water ).<br /><br />As for mamals you can do mamals.giveBirth() to a group of them. Elephants would take up to a year while humans 9 months. <br /><br />Classification or inheritance has been part of the sciences for centuries. To make claim that inheritence is not part of the real world is just innacurate.<br /><br />Again i agree with your general thesis which is that inherietance in OO should be avoided because of the hierarchical structure it creates as well as the rigidity. But this has nothing to do with the absence of inheritence in the real world.<br /><br />I'm off my soap box.
  • 6 ksuh // Sep 8, 2004 at 5:04 PM

    > To make claim that inheritence is not part of the real world is just innacurate.<br /><br />I think what Sean means by "real world" is programming designs.
  • 7 seancorfield // Sep 8, 2004 at 5:04 PM

    Obelix, if you model the 'real world' in a program then you might have a 'giveBirth()' method on your 'Mammal' class but that is a programmatic construction - we, as (pseudo-)scientific humans, apply that level of order to the real world in order to help us better understand the 'model' behind the real world. You're thinking as a programmer.<br /><br />The only inheritance in the real world is genetic and that is only vaguely comparable to what we programmers call 'inheritance'.
  • 8 Nik Khilnani // Sep 8, 2004 at 5:04 PM

    I think im going to have a headache... but anyway... The problem lies not in inheritence but in not understanding when to use it. I agree with Obelix... in the real world of programming , inheritence is used quite a bit, used where it is needed not every place it can/could/may be used.<br /><br />Sam said he used inheritence quite a bit but then later on needed to borrow functionality.... i would say 2 things.. either the original design didnt anticipate objects at the same level borrwing functionality or inheritence was over used or used incorrectly... It may be easier or safer to use composition but that doesnt mean there isnt place for inheritence or its bad.<br /><br />OOP books are not real world examples. they are not meant to be. They are teaching books, to show you what can be done and how to do it. You need to apply what they show you, use descretion, apply the informatioin and not follow it blindly. <br /><br />nik
  • 9 Obelix // Sep 8, 2004 at 5:04 PM

    I think in the end we will agree to disagree about whether inheritence in the real world is rare or not rare. I feel that this is secondary to your point about inheritence in the programming world.<br /><br />I would like to add that inheritence because of its complexity and nesting, requires a greater degree of foresite on the part of the architect. What i mean is by *coupling* components through an inheritence structure the architect needs to be aware of future changes in functionality and/or additions. Composition because of its loose couplings is more apt at adapting to a changing set of requirements than inheritance. And there folks lie the issue.
  • 10 Hal Helms // Sep 8, 2004 at 5:04 PM

    What's interesting to me is that you can have a fully OO language that doesn't support inheritance at all! In my experience, Sean's absolutely right about this. Even if something can be defined as "is a" doesn't mean that it should be. For example, an hourly employee IS A employee, but if you define that in an inheritance rleationship, you're going to run into real problems when the person moves from hourly employee to salaried employee.
  • 11 Obelix // Sep 8, 2004 at 5:04 PM

    I agree with Sean as well, I just disagree with the analogy or example used to prove his point. Inheritance may or may not have a place in a particular software project. It really depends on the ocntext (known variables vs unknown and propencity for feature creep and additional modules)<br /><br />I am however curious to know what the issues would be with the employee example you gave? To me it actually seem like a good example for inheritence...
  • 12 seancorfield // Sep 8, 2004 at 5:04 PM

    Hal's example is a classic misuse of inheritance that is incredibly common in novice OO code - the correct way to model this is to use a Party-Role relationship: an employee (the party) "has-a" compensation (the role which might hourly, salaried, etc). The role is an appropriate use of inheritance (hourly "is-a" compensation, salaried "is-a" compensation).<br /><br />The same applies to roles like manager, secretary, executive: an employee "has-a" jobtype and manager "is-a" jobtype.<br /><br />Why? Because when you change an employee's compensation or their jobtype, you are not changing the employee itself (the name, SSN etc all stay the same), all you are changing is an attribute of that employee.<br /><br />It's very hard to change the *type* of an object - it's easy to change an attribute. That's why composition is better than inheritance in many cases.