Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In the last few months, the mantra "favor composition over inheritance" seems to have sprung up out of nowhere and become almost some sort of meme within the programming community. And every time I see it, I'm a little bit mystified. It's like someone said "favor drills over hammers." In my experience, composition and inheritance are two different tools with different use cases, and treating them as if they were interchangeable and one was inherently superior to the other makes no sense.

Also, I never see a real explanation for why inheritance is bad and composition is good, which just makes me more suspicious. Is it supposed to just be accepted on faith? Liskov substitution and polymorphism have well-known, clear-cut benefits, and IMO comprise the entire point of using object-oriented programming, and no one ever explains why they should be discarded in favor of composition.

Does anyone know where this concept comes from, and what the rationale behind it is?

share|improve this question
36  
As others have pointed out, it's been around a long time - I'm surprised you're just now hearing of it. It's intuitive to anyone who has been building big systems in languages like Java for any amount of time. It's core to any interview I ever give and when a candidate starts talking about inheritance, I begin to doubt their skill level and amount of experience. Here's a good introduction to why inheritance is a brittle solution (there are many many others): artima.com/lejava/articles/designprinciples4.html –  Janx Apr 4 '11 at 23:59
4  
@Janx: Maybe that's it. I don't build big systems in languages like Java; I build them in Delphi, and without Liskov substitution and polymorphism we'd never get anything done. Its object model is different in certain ways than Java's or C++'s, and a lot of the problems that this maxim seems to be meant to solve don't really exist, or are much less problematic, in Delphi. Different perspectives from different points of view, I guess. –  Mason Wheeler Apr 5 '11 at 0:13
9  
I spent several years on a team building relatively large systems in Delphi and tall inheritance trees certainly bit our team and caused us significant pain. I suspect that your attention to the SOLID principles is helping you to avoid the problem areass, not your use of Delphi. –  Bevan Apr 5 '11 at 8:33
6  
Last few months?!? –  Jas Apr 5 '11 at 12:41
6  
IMHO that concept has never been fully adjusted to the variety of languages that support both interface inheritance (i.e., subtyping with pure interfaces) and implementation inheritance. Too many people follow this mantra and don't use enough interfaces. –  Uri Apr 5 '11 at 15:04

14 Answers 14

up vote 84 down vote accepted

Though I think I've heard composition-vs-inheritance discussions long before GoF, I can't put my finger on a specific source. Might have been Booch anyway.

<rant>

Ah but like many mantras, this one has degenerated along typical lines:

  1. it is introduced with a detailed explanation and argument by a well-respected source who coins the catch-phrase as a reminder of the original complex discussion
  2. it is shared with a knowing part-of-the-club wink by a few in-the-know for a while, generally when commenting on n00b mistakes
  3. soon it is repeated mindlessly by thousands upon thousands who never read the explanation, but love using it as an excuse not to think, and as a cheap and easy way to feel superior to others
  4. eventually, no amount of reasonable debunking can stem the "meme" tide - and the paradigm degenerates into religion and dogma.

The meme, originally intended to lead n00bs to enlightenment, is now used as a club to bludgeon them unconscious.

Composition and inheritance are very different things, and should not be confused with each other. While it is true that composition can be used to simulate inheritance with a lot of extra work, this does not make inheritance a second-class citizen, nor does it make composition the favorite son. The fact that many n00bs try to use inheritance as a shortcut does not invalidate the mechanism, and almost all n00bs learn from the mistake and thereby improve.

Please THINK about your designs, and stop spouting slogans.

</rant>

share|improve this answer
11  
Booch argues that implementation inheritance introduces high coupling among classes. On the other hand, he considers inheritance the key concept that distinguishes OOP from procedural programming. –  Nemanja Trifunovic Apr 5 '11 at 2:06
10  
There should be a word for this kind of thing. Premature Regurgitation, maybe? –  Jörg W Mittag Apr 5 '11 at 2:08
6  
@Jörg: You know what will happened to a term like Premature Regurgitation? Exactly what is explained above. :) (Btw. when is regurgitation ever not premature?) –  Bjarke Freund-Hansen Apr 5 '11 at 13:18
4  
@Nemanja: Right. The question is whether this coupling is really bad. If the classes are conceptually strongly coupled and conceptually form a supertype-subtype relationship, and could never be conceuptually decoupled even if they're formally decoupled at the language level, then strong coupling is fine. –  dsimcha Apr 6 '11 at 15:44
4  
The mantra is simple, "just because you can shape play-doh to look like anything doesn't mean that you should make everything out of play-doh." ;) –  Evan Plaice Apr 19 '12 at 3:56

Some possible arguments for composition:

Composition is slightly more language / framework agnostic
Inheritance and what it enforces / requires / enables will differ between languages in terms of what the sub/superclass have access to and what performance implications it may have wrt virtual methods etc. Composition is quite basic and requires very little language support, and thus implementations across different platforms / frameworks can share composition patterns more easily.

Composition is a very simple and tactile way of building objects
Inheritance is relatively easy to understand, but still not as easily demonstrated in real life. Many objects in real life can be broken down into parts and composed. Say a bicycle can be built using two wheels, a frame, a seat, a chain etc. Easily explained by composition. Whereas in an inheritance metaphor you could say that a bicycle extends a unicycle, somewhat feasible but still much further from the real picture than composition (obviously this is not a very good inheritance example, but the point remains the same). Even the word inheritance (at least of most US English speakers I would expect) automatically invokes a meaning along the lines "Something passed down from a deceased relative" which has some correlation with its meaning in software, but still only loosely fits.

Composition is almost always more flexible
Using composition you can always choose to define your own behavior or simply expose that part of your composed parts. This way you face none of the restrictions that may be imposed by an inheritance hierarchy (virtual vs. non-virtual etc.)

So, it could be because Composition is naturally a simpler metaphor that has less theoretical constraints than inheritance. Furthermore, these particular reasons may be more apparent during design time, or possibly stick out when dealing with some of the pain points of inheritance.

Disclaimer:
Obviously its not this clear cut / one way street. Each design merits evaluation of several patterns / tools. Inheritance is widely used, has lots of benefits and many times is more elegant than composition. These are just some possible reasons one could use when favoring composition.

share|improve this answer

I think this sort of advice is like saying "prefer driving to flying". That is, planes have all sorts of advantages over cars, but that comes with a certain complexity. So if many people try to fly from the city centre to the suburbs, the advice they really, really need to hear is that they don't need to fly, and in fact, flying will just make it more complicated in the long run, even if it seems cool/efficient/easy in the short term. Whereas when you do need to fly, it's generally supposed to be obvious.

Likewise, inheritence can do things composition can't, but you should use that when you need it, and not when you don't. So if you're never tempted to just assume you need inheritence when you don't, then you don't need the advice of "prefer composition". But many people do, and do need that advice.

It's supposed to be implicit that when you really DO need inheritance, it's obvious, and you should use it then.

Also, Steven Lowe's answer. Really, really that.

share|improve this answer
    
I like your analogy –  barrylloyd Apr 5 '11 at 12:24
    
Thank you, Barry. –  Jack V. Apr 13 '11 at 10:37

Inheritance isn't inherently bad, and composition isn't inherently good. They are merely tools that an OO programmer can use to design software.

When you look at a class, is it doing more than it absolutely should (SRP)? Is it duplicating functionality unnecessarily (DRY), or is it overly interested in the properties or methods of other classes (Feature Envy)?. If the class is violating all of these concepts (and possibly more), is it attempting to be a God Class. These are a number of problems that can occur when designing software, none of which is necessarily an inheritance problem, but which can quickly create major headaches and brittle dependencies where polymorphism has also been applied.

The root of the problem likely to be less a lack of understanding about inheritance, and more one of either poor choice in terms of design, or perhaps not recognizing "code smells" relating to classes that are not adhering to the Single Responsibility Principle. Polymorphism and Liskov Substitution need not be discarded in favour of composition. Polymorphism itself can be applied without relying on inheritance, these are all quite complimentary concepts. If applied thoughtfully. The trick is to aim to keep your code simple, and clean, and to not to succumb to being overly concerned about the number of classes that you need to create in order to create a robust system design.

In so far as the issue of favouring composition over inheritance, this is really just another case of the thoughtful application of the design elements that make the most sense in terms of the problem being solved. If you don't need to inherit behaviour, then you probably shouldn't as composition will help to avoid incompatibilities and major refactoring efforts later on. If on the other hand you find that you are repeating a lot of code such that all of the duplication is centred on a group of similar classes, then it may be that creating a common ancestor would help to reduce the number of identical calls and classes you might need to repeat between each class. Thus, you are favouring composition, yet you aren't assuming that inheritance is never applicable.

share|improve this answer

In one of the comment, Mason mentionned that one day we would be speaking about Inheritance considered harmful.

I hope so.

The problem with inheritance is at once simple, and deadly, it does not respect the idea that one concept should have one functionality.

In most OO-languages, when inheriting from a base class you:

  • inherit from its interface
  • inherit from its implementation (both data and methods)

And here become the trouble.

This is not the only approach, though 00-languages are mostly stuck with it. Fortunately interfaces / abstract classes exist in those.

Also, the lack of ease for doing otherwise contribute to making it largely used: frankly, even knowing this, would you inherit from an interface and embed the base class by composition, delegating most of the method calls ? It would be considerably better though, you'd even be warned if suddenly a new method pops in the interface and would have to choose, consciously, how to implement it.

As a counter-point, Haskell only allow to use the Liskov Principle when "deriving" from pure interfaces (called concepts) (1). You cannot derive from an existing class, only composition allow you to embed its data.

(1) concepts may provide a sensible default for an implementation, but since they have no data, this default can only be defined in term of the other methods proposed by the concept or in term of constants.

share|improve this answer

"Composition over inheritance" is a short (and apparently misleading) way of saying "When feeling that the data (or behaviour) of a class should be incorporated into another class, always consider using composition before blindly applying inheritance".

Why is this true ? Because inheritance creates tight, compile-time coupling between the 2 classes. Composition in contrast is loose coupling, wich among others enables clear separation of concerns, the possibility of switching dependencies at runtime and easier, more isolated dependency testability.

That only means inheritance should be handled with care because it comes at a cost, not that it isn't useful. Actually, "Composition over inheritance" often ends up being "Composition + inheritance over inheritance" since you often want your composed dependency to be an abstract superclass rather than the concrete subclass itself. It allows you to switch between different concrete implementations of your dependency at runtime.

For that reason (among others), you'll probably see inheritance used more often in the form of interface implementation or abstract classes than vanilla inheritance.

A (metaphorical) example could be :

"I have a Snake class and I want to include as part of that class what happens when the Snake bites. I would be tempted to have the Snake inherit a BiterAnimal class that has the Bite() method and override that method to reflect venomous bite. But Composition over Inheritance warns me that I should try to use composition instead... In my case, this could translate into the Snake having a Bite member. Bite class could be abstract (or an interface) with several subclasses. This would allow me nice things like having VenomousBite and DryBite subclasses and being able to change bite on the same Snake instance as the snake grows of age. Plus handling all the effects of a Bite in its own separate class could allow me to reuse it in that Frost class, because frost bites but isn't a BiterAnimal, and so on..."

share|improve this answer
3  
Very good example with the Snake. I met a similar case recently with my own classes –  Maksee Apr 19 '12 at 6:59

The actual quote comes, I believe, from Joshua Bloch's "Effective Java", where it is the title of one of the chapters. He claims that inheritance is safe within a package and wherever a class has been specifically designed and documented for extension. He claims, as others have noted, that inheritance breaks encapsulation because a subclass depends on the implementation details of its superclass. This leads, he says, to fragility.

Although he doesn't mention it, it seems to me that single inheritance in Java means that composition gives you much more flexibility than inheritance.

share|improve this answer

The simple answer is: inheritance has greater coupling than composition. Given two options, of otherwise equivalent qualities, choose the one that is less coupled.

share|improve this answer
2  
But that's the whole point. They're not "otherwise equivalent." Inheritance enables Liskov substitution and polymorphism, which are the entire point of using OOP. Composition doesn't. –  Mason Wheeler Apr 5 '11 at 3:11
3  
Polymorphism/LSP are not "the whole point" of OOP, they are one feature. There is also encapsulation, abstractions etc. Inheritence implies an "is a" relationship, agregation models a "has a" relationship. –  Steve Haigh Apr 5 '11 at 9:18
    
@Steve: You can do abstractions and encapsulation in any paradigm that supports the creation of data structures and procedures/functions. But polymorphism (specifically referring to virtual method dispatching in this context) and Liskov substitution are unique to object-oriented programming. That's what I meant by that. –  Mason Wheeler Apr 5 '11 at 14:59
3  
@Mason: The guideline is to "favor composition over inheritance." In no way does this mean don't use or even avoid inheritance. All it says that when all other things are equal, choose composition. But if you need inheritance, use it! –  Jeffrey Faust Apr 5 '11 at 20:27

Here are my two cents (beyond all the excellent points already raised):

IMHO, It comes down to the fact that most programmers don't really get inheritance, and end up overdoing it, partially as a result of how this concept is taught. This concept exists as a way to try to dissuade them from overdoing it, instead of focusing on teaching them how to do it right.

Anyone who has spent time teaching or mentoring knows that this is what often happens, especially with new developers who have experience in other paradigms:

These developers initially feel that inheritance is this scary concept. So they end up creating types with interface overlaps (e.g., same specified behavior without common subtyping), and with globals for implementing common pieces of functionality.

Then (often as a result of overzealous teaching), they learn about the benefits of inheritance, but it's often taught as the catch-all solution to reuse. They end up with a perception that any shared behavior must be shared through inheritance. This is because the focus is often on implementation inheritance rather than subtyping.

In 80% of the cases that's good enough. But the other 20% are where the problem starts. For the sake of avoiding rewriting and for making sure they have taken advantage of sharing implementation, they start designing their hierarchy around the intended implementation rather than the underlying abstractions. The "Stack inherits from doubly-linked list" is a good example of this.

Most teachers do not insist on introducing the concept of interfaces at this point, because it's either another concept, or because (in C++) you have to fake them using abstract classes and multiple inheritance which is not taught at this stage. In Java, many teachers do not distinguish the "no multiple inheritance" or "multiple inheritance is evil" from the importance of interfaces.

All this is compounded by the fact that we've learned so much of the beauty of not having to write superfluous code with implementation inheritance, that tons of straightforward delegation code looks unnatural. So composition looks messy, which is why we need these rules of thumbs to push new programmers to use them anyway (which they overdo as well).

share|improve this answer
    
Thats a true part of education. You have todo the higher courses to get i.e. the rest of 20% but you, as the student, was just teached the basic and and perhaps intermediate courses. In the ending, you feel well teached because you did your courses well (and simply dont see it just a pin on the ladder). It's just a part of reality and our best bet is to understand it's side effects, not attack the coders. –  Independent Apr 19 '12 at 5:24

It's a reaction to the observation that OO beginners tend to use inheritance when they don't need to. Inheritance is certainly not a bad thing, but it can be overused. If one class just needs functionality from another, then composition will probably work. In other circumstances, inheritance will work and composition won't.

Inheriting from a class implies a lot of things. It implies that a Derived is a type of Base (see the Liskov Substitution principle for the gory details), in that whenever you use a Base it would make sense to use a Derived. It gives the Derived access to the protected members and member functions of Base. It's a close relationship, meaning it has high coupling, and changes to one are more likely to require changes to the other.

Coupling is a bad thing. It makes programs harder to understand and modify. Other things being equal, you should always select the option with less coupling.

Therefore, if either composition or inheritance will do the job effectively, choose composition, because it's lower coupling. If composition will not do the job effectively, and inheritance will, choose inheritance, because you have to.

share|improve this answer

Experience.

Like you say they are tools for different jobs, but the phrase came about because people were not using it in that way.

Inheritance is primarily a polymorphic tool, but some people, much to their later peril, attempt to use it as a way of reusing/sharing code. The rationale being "well if I inherit then I get all the methods for free", but ignoring the fact that these two classes potentially have no polymorphic relationship.

So why favour composition over inheritance - well simply because more often than not the relationship between classes is not a polymorphic one. It exists simply to help remind people to not knee jerk respond by inheriting.

share|improve this answer
4  
So basically, you can't say "you shouldn't be using OOP in the first place if you don't understand Liskov substitution," so you say "favor composition over inheritance" instead as an attempt to limit the damage done by incompetent coders? –  Mason Wheeler Apr 4 '11 at 23:08
9  
@Mason: Like any mantra, "favor composition over inheritance" is targeted at beginner programmers. If you already know when to use inheritance and when to use composition then it's pointless to repeat a mantra like that. –  Dean Harding Apr 4 '11 at 23:14
5  
@Dean - I'm not sure beginner is the same as one who doesn't understand inheritance best practices. I think there is more to it than that. Poor inheritance is the cause of many, many headaches in my job and it's not code written by programmers who would be considered "beginners". –  NickC Apr 4 '11 at 23:27
2  
@Renesis: First thing I think of when I hear that is, "some people have ten years of experience, and some people have one year of experience repeated ten times." –  Mason Wheeler Apr 4 '11 at 23:46
5  
I was designing a fairly large project right after first "Getting" OO and relied on it heavily. Although it worked well, I constantly found the design brittle--causing minor irritations here and there and sometimes making certain refactors a complete bitch. It's kind of difficult to explain the whole experience, but the phrase "Favor Compisition over Inheritence" describes it EXACTLY. Note that it does not say or even imply "Avoid Inheritence", it simply gives you a little nudge when the choice is not obvious. –  Bill K Nov 28 '12 at 18:04

Perhaps you just noticed people saying this in the last few months, but it has been known to good programmers for a lot longer than that. I've certainly been saying it where appropriate for about a decade.

The point of the concept is that there is a large conceptual overhead to inheritance. When you are using inheritance, then every single method call has an implicit dispatch in it. If you have deep inheritance trees, or multiple dispatch, or (even worse) both, then figuring out where the particular method will dispatch to in any particular call can become a royal PITA. It makes correct reasoning about the code more complex, and it makes debugging harder.

Let me give a simple example to illustrate. Suppose that deep in an inheritance tree, someone named a method foo. Then someone else comes along and adds foo at the top of the tree, but doing something different. (This case is more common with multiple inheritance.) Now that person working at the root class has broken the obscure child class and probably doesn't realize it. You could have 100% coverage with unit tests and not notice this breakage because the person at the top wouldn't think of testing the child class, and the tests for the child class don't think of testing the new methods created at the top. (Admittedly there are ways to write unit tests that will catch this, but there are also cases where you can't easily write tests that way.)

By contrast when you use composition, at each call it is usually clearer what you are dispatching the call to. (OK, if you're using inversion of control, for instance with dependency injection, then figuring out where the call goes can also get problematic. But usually it is simpler to figure out.) This makes reasoning about it easier. As a bonus, composition results in having methods segregated from each other. The above example should not happen there because the child class would move off to some obscure component, and there is never a question about whether the call to foo was intended for the obscure component or the main object.

Now you are absolutely right that inheritance and composition are two very different tools that serve two different types of things. Sure inheritance carries conceptual overhead, but when it is the right tool for the job, it carries less conceptual overhead than trying to not use it and do by hand what it does for you. Nobody who knows what they are doing would say that you should never use inheritance. But be sure it is the right thing to do.

Unfortunately many developers learn about object oriented software, learn about inheritance, and then go out to use their new axe as often as possible. Which means that they try to use inheritance where composition was the right tool. Hopefully they will learn better in time, but frequently this does not happen until after a few removed limbs, etc. Telling them up front that it is a bad idea tends to speed up the learning process and reduce injuries.

share|improve this answer
3  
All right, I guess that makes sense from a C++ perspective. That's something I never thought of, because it's not an issue in Delphi, which is what I use most of the time. (There's no multiple inheritance, and if you have a method in a base class and another method by the same name in a derived class that does not override the base method, the compiler will issue a warning, so you don't accidentally end up with this sort of problem.) –  Mason Wheeler Apr 4 '11 at 23:51
1  
@Mason: Ander's version of Object Pascal (a.k.a. Delphi) is superior to C++ and Java when it comes to the fragile base class inheritance problem. Unlike C++ and Java, overloading of an inherited virtual method is not implicit. –  bit-twiddler Apr 5 '11 at 1:37
2  
@bit-twiddler, what you say about C++ and Java can be said about Smalltalk, Perl, Python, Ruby, JavaScript, Common Lisp, Objective-C, and every other language I've learned that provides any form of OO support. That said, googling suggests that C# follows Object Pascal's lead. –  btilly Apr 5 '11 at 1:57
3  
That's because Anders Hejlsberg designed Borland's flavor of Object Pascal (a.k.a. Delphi) and C#. –  bit-twiddler Apr 5 '11 at 2:15

It's not a new idea, I believe it was actually introduced in the GoF design patterns book, which was published in 1994.

The main problem with inheritance is that it's white-box. By definition, you need to know the implementation details of the class you're inheriting from. With composition, on the other hand, you only care about the public interface of the class you're composing.

From the GoF book:

Inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation'

The wikipedia article on the GoF book has a decent introduction.

share|improve this answer
12  
I don't agree with that. You don't need to know the implementation details of the class you're inheriting from; only the public and protected members exposed by the class. If you have to know the implementation details, then either you or whoever wrote the base class is doing something wrong, and if the flaw is in the base class, composition won't help you fix/work around it. –  Mason Wheeler Apr 4 '11 at 23:15
16  
How can you disagree with something you haven't read? There's a solid page and a half of discussion from GoF that you are getting just a tiny view of. –  philosodad Apr 4 '11 at 23:30
6  
@pholosodad: I'm not disagreeing with something I haven't read. I'm disagreeing with what Dean wrote, that "By definition, you need to know the implementation details of the class you're inheriting from," which I have read. –  Mason Wheeler Apr 4 '11 at 23:47
10  
What I wrote is just a summary of what's described in the GoF book. I might've worded it a little strongly (you don't need to know all the implementation details) but that's the general reason why the GoF says to favour composition over inheritance. –  Dean Harding Apr 5 '11 at 0:05
1  
Correct me if I'm wrong but I see it as, "favor explicit class relationships (ie Interfaces) over implicit (ie inheritance)." The former tell you what you need without telling you how to do it. The latter not only tell you how to do it but will make you regret it down the road. –  Evan Plaice Apr 19 '12 at 4:03

To answer part of your question, I believe this concept first appeared in the GOF Design Patterns: Elements of Reusable Object-Oriented Software book, which was first published in 1994. The phrase appears at the top of page 20, in the introduction:

Favor object composition over inheritance

They preface this statement with a brief comparison of inheritance with composition. They don't say "never use inheritance".

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.