Bernard Sumption has a post titled Inheritance is evil, and must be destroyed: part 1:
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.
I couldn't have said it better myself. Remember that next time you type extends and re-think the implementation before taking the easy route. Unless, of course, you just want to be like Java ;-)
8 comments
Seems like he's got some cases where interfaces (or, yes, composition) would be a better solution.
But I have cases where, say, if I'm building a CMS, I have a ContentObject class that has generalized methods to determine where it's been published, etc. If I have two types of content, Document and Event, I fail to see why extending ContentObject for each one is bad.
Now if I have another type, Author, and each Document needs an Author, it's a has-a relationship. Extending Author to get the author's name as part of the Document would be wrong. Instead it should be $document->author->getName();
But in the first case, if I need to implement a publishTo($page_id) method, I'd rather do it once in ContentObject, so I can change that implementation in one place. Am I missing something that makes that a bad idea?
Inheritance in languages like php is very limited. You can only inherit from one object. (Which I think is perfectly fine.) Whereas you can use composition, decorator and other similar patterns many, many times.
Jedi objects in to their discussion. :-)At any rate, it's the same as their being many paths to the top of a mountain: as long as they all lead to the top, you get to the same place.
