Thursday, October 11th, 2007

Inheritance is evil, and must be destroyed: part 1

Category: Articles

When we wrote about Bernard Sumption’s Animator.js there was a lot of “interest” in Bernies position that OO inheritance sucks.

Bernie decided to fuel the fire and expanded his thoughts, explaining how the strategy pattern is in fact your saviour ;)

All of the pain caused by inheritance can be traced back to the fact that inheritance forces ‘is-a’ rather than ‘has-a’ relationships. If class R2Unit extends Droid, then a R2Unit is-a Droid. If class Jedi contains an instance variable of type Lightsabre, then a Jedi has-a Lightsabre.

The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship.

The article takes the world of Jedi and then writes a real example using Balls and BouncingBalls. He also explains why he thinks that Flash’s DisplayObject hierarchy is good, and that EventDispatcher is bad.

Posted by Dion Almaer at 10:10 am

3.2 rating from 36 votes


Comments feed TrackBack URI

The problems Bernard describes in his article can usually be solved in an elegant manner using abstract classes and interfaces. However, since js was never intended to be used in an OOP context, it is also reasonable that the language doesn’t provide the facilities for those concepts.
Personally I agree with Bernard and think js is quite expressive relying solely on its prototype based nature. In fact, I like prototype (not the lib) so much I find myself constantly wishing other languages would offer something similar.

Comment by Anonymous — October 11, 2007

Bernard’s arguments are actually arguments for multiple inheritance. It doesn’t have anything to do with inheritance being evil, it has do with the lack of ability with linear (non-multiple) inheritance. I would love modern languages to support multiple inheritance so delegation wouldn’t have to be used to address the issues Bernard faces.

Comment by Kris Zyp — October 11, 2007

“The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship.”

You’ve got to be kidding me. In OOP, has-a relationships are implemented with polymorphismic interfaces. Inherited relationships are not about reimplementing common properties but about giving specifics to otherwise generic details. If a tiger is a cat and cat has four legs, does the tiger’s having four legs share commonality with ‘cat’, or is the four-leggedness INFERRED by it being a cat? In inheritence, it is inferred and thereby strongly enforced.

In practical terms, if you’re messing with inheritence models where is-a doesn’t fit, then the design went wrong somewhere, not the nature of inheritence itself.

Comment by Jon Davis — October 11, 2007

Javascript is OO but not a class-based is prototype-based. People are trying to create a class-based jv which is to a bad way of doing things. Inheritance is not evil, multiple inheritance is evil. The problem is resolving every problem with inheritance. Inheritance is for reusing knowledge, not code nor variables. Inheritance and delegation are equally powerful, if your environment let you, but generally speaking, delegation is more powerful.

Comment by cocotapioca — October 11, 2007

Javascript is ultra flexible, I think if we want to use it for strong oop we can bend it to serve our needs; btw in an oop manner I don’t get why multiple inheritance is evil? Isn’t jedi+darkpoweruser=darkjedi and hippo+darkpoweruser=darkhippo okay? Do I miss something fundamental here?

Comment by deadcabbit — October 11, 2007

The arguments against multiple inheritance can be described more accurately than “is evil” as cocotapioca did. Basically it boils down multiple inheritance being more complex and harder to learn. But it is more powerful and does solve Bernard’s challenge (!= “evil”).

Comment by Kris Zyp — October 11, 2007

The reason he gets flack (as he says) is because he somehow seems to make the point that inheritance is evil, instead of just writing an article on how to add functionality to several otherwise unrelated classes. It sounds like multiple inheritance is what he would like, but the mainstream OO languages do not support it. I believe people like Anders Hejlsberg (C# designer) have very good reasons not to include something. But with this guys headline, it’s no wonder he gets criticized.

Comment by mike — October 11, 2007

…thanks for the good article, makes sense about the ‘has-a’ distinction.

Comment by Mark Holton — October 11, 2007

Post advertisement at . There you can offer your services, find gigs (short term jobs) or long term jobs. It is good place who would like to work remotely. Also there you can promote your website, your services. Between its absolutely free to post and no registration needed.

Comment by Vytas — October 12, 2007

I agree the multiple inheritance would solve the problem here but as most languages don’t have it you have to implement the sort of code in article.

However, I think he has led himself into arguing for inheritance as again as the final piece of code has two hardcoded “strategies” which you have to check with an if else (that seems nasty to me). Why not have a list/collection of strategies which when take the MovieClip as a parameter in their nextValue function and loop over all in the list.
“But should the strategies update y or alpha” i hear you cry, well both. If you extend the AbeSineStrategy with VerticalMovementStategy and FadingStrategy and implement the nextValue(MovieClip) function to update the relevant attribute of the MovieClip then you have a nice solution which can be extended to have multiple stategies per object and you are reusing code through inheritance by extending the AbeSineStrategy.

Like the article just disagree with the implementation :-).

Comment by Owen Fellows — October 12, 2007

The average programmer sees inheritance as a way to save typing. Not data typing, keyboard typing.

I think it’s like pointer arithmetic: every good programmer on first exposure thinks how wonderfully convenient it is and thinks up all sorts of beautifully elegant solutions. However, if you step away from hypothetical Cat and Car classes and view these beasts in their native environments (large IT departments staffed with semi-skilled programmers) what you see isn’t quite so pretty.

Inheritance breaks encapsulation, reduces code reusability (it’s far more fragile than interfaces and/or delegation), and clutters namespaces. Polymorphism is wonderful and I can’t imagine living without it, but in most cases it works just fine without inheritance. In short I agree with Bernie – inheritance has its place but it’s vastly overused.

Comment by Scott Vachalek — October 12, 2007

various commentators: “What Bernie really wants is MI”

[weeps] oh no, multiple inheritance will not solve the problems I describe in the article. MI is very hard to use well because it binds code sharing and type hierarchies together in a tangled mess. It is a hack to try and fix the problems of a language feature that was never very good in the first place.

Owen Fellows: Why not have a list/collection of strategies which when take the MovieClip as a parameter in their nextValue function and loop over all in the list.

Very good point. The example in the article was kept simple, but see this comment for an example of just that.

Comment by Bernard Sumption — October 12, 2007

“..but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship…”

Which is wrong. The question is not whether is-a OR has-a, but which one of those fits the best. It’s too much to argue the whole thing, but one should make a difference concerning polymorphy. If wanted and senseful, is-a would be ok. Otherwhise has-a. A beamer IS a car, while a dialogwindow HAS a dialog.

There is plenty of information in the net since the 90s… so I don’t understand what’s so new about it. Is it neccessary to rewrite every article because you are looking at it from the JavaScript side? It is a well known fact, that the OO approach is not the last and best one, but that’s nothing new.

Comment by Mate — October 13, 2007

In a single inheritance language he’s to some extend right, in a MI language (like JavaScript is) this is pure BULLSHIT…!
The reason is that in an Multiple Inheritance language it’s not “IS A” it is an “AMONG OTHER THINGS IS A”…
This means you can have very small classes which contains stuff like “DarkPowers”, “Mecha”, “Human” etc and when you inherit you inherit from a bunch of “aspects” instead of reducing your option everytime you “commit” inheritance…
Somebody REALLY needs to put these “earlier Java developers” back to the place where they belong in regards to LSP, OOP, OOD and OOA…!

Comment by Thomas Hansen — October 13, 2007

Thanks Bernie for reply.

I see what you mean that you can overuse inheritance. In my example above I suggested extending the AbeSineStrategy but this is actually incorrect as there should be a “AbeSine” class that is used by a Strategy (has-a) instead of being an “AbeSine” itself. This encorages code reuse and encapsulation as the AbsSine object is self contained and can be used by other code if required.

It seems to me that you should inherit “process” and deligate “implementation”. e.g. With Struts Actions you can implement a super class that handles Cancel or Submit operations but the actual implementations of those should not be inherited but implemented (a defined by an interface) in the sub class. If you want to extend the sub class to reuse some of its implementation then move the implementation into a delgated class and call from two seperate (none inheriting sub classes).

I would like to hear if anyone has objection the above paragraph and why as it seems simpler for maintainance and testing to implement it this way.

Comment by Owen Fellows — October 16, 2007

Leave a comment

You must be logged in to post a comment.