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.

I always read that composition is to be preferred over inheritance. A blog post on unlike minds, for example, advocates using composition over inheritance, but I can't see how polymorphism is achieved.

But I have a feeling that when people say prefer composition, they really mean prefer a combination of composition and interface implementation. How are you going to get polymorphism without inheritance?

Here is a concrete example where I use inheritance. How would this be changed to use composition, and what would I gain?

Class Shape
{
string name;
public:
void getName();
virtual void draw()=0;
}

Class Circle: public Shape
{
void draw(/*draw circle*/);
}
share|improve this question
25  
No, when people say prefer composition they really mean prefer composition, not never ever ever use inheritance. Your whole question is based on a faulty premise. Use inheritance when it's appropriate. –  Bill the Lizard Feb 9 '12 at 2:59
2  
You might also want to take a look at programmers.stackexchange.com/questions/65179/… –  vjones Feb 9 '12 at 3:25
    
Thanks for the edit, Mark! –  illmath Feb 9 '12 at 8:31
1  
I agree with the Bill, I have see using inheritance a common practice in GUI development. –  Prashant Feb 10 '12 at 7:57
1  
You want to use composition because a square is just the composition of two triangles, in fact I think all shapes other than ellipse are just compositions of triangles. Polymorphism is about contractual obligations and 100% removed from inheritance. When triangle get's a bunch of oddities added to it because somebody wanted to make it capable of generating pyramids, if you inherit from Triangle you're going to get all of that even though you're never going to generate a 3d pyramid from your hexagon. –  Jimmy Hoffa Feb 11 '13 at 22:28

4 Answers 4

up vote 25 down vote accepted

Polymorphism does not necessarily imply inheritance. Often inheritance is used as an easy means to implement Polymorphic behaviour, because it is convenient to classify similar behaving objects as having entirely common root structure and behaviour. Think of all those car and dog code examples you've seen over the years.

But what about objects that aren't the same. Modelling a car and a planet would be very different, and yet both might want to implement Move() behaviour.

Actually, you basically answered your own question when you said "But I have a feeling that when people say prefer composition, they really mean prefer a combination of composition and interface implementation.". Common behaviour can be provided through interfaces and a behavioural composite.

As to which is better, the answer is somewhat subjective, and really comes down to how you want your system to work, what makes sense both contextually and architecturally, and how easy it will be to test and maintain.

share|improve this answer

Preferring composition isn't just about polymorphism. Although that is part of it, and you are right that (at least in nominally typed languages) what people really mean is "prefer a combination of composition and interface implementation." But, the reasons to prefer composition (in many circumstances) are profound.

Polymorphism is about one thing behaving multiple ways. So, generics/templates are a "polymorphic" feature in so far as they allow a single piece of code to vary its behavior with types. In-fact, this type of polymorphism is really the best behaved and is generally referred to as parametric polymorphism because the variation is defined by a parameter.

Many languages provide a form of polymorphism called "overloading" or ad hoc polymorphism where multiple procedures with the same name are defined in an ad hoc manner, and where one is chosen by the language (perhaps the most specific). This is the least well behaved kind of polymorphism, since nothing connects the behavior of the two procedures except developed convention.

A third kind of polymorphism is subtype polymorphism. Here a procedure defined on a given type, can also work on a whole family of "subtypes" of that type. When you implement an interface or extend a class you are generally declaring your intention to create a subtype. True subtypes are governed by Liskov's Substitution Principle, which says that if you can prove something about all objects in a supertype you can prove it about all instances in a subtype. Life gets dangerous though, since in languages like C++ and Java, people generally have unenforced, and often undocumented assumptions about classes which may or may not be true about their subclasses. That is, code is written as if more is provable than it really is, which produces a whole host of issues when you subtype carelessly.

Inheritance is actually independent of polymorphism. Given some thing "T" which has a reference to itself, inheritance happens when you create a new thing "S" from "T" replacing "T"s reference to itself with a reference to "S". That definition is intentionally vague, since inheritance can happen in many situations, but the most common is subclassing an object which has the effect of replacing the this pointer called by virtual functions with the this pointer to the subtype.

Inheritance is a dangerous like all very powerful things inheritance has the power to cause havoc. For example, suppose you override a method when inheriting from some class: all is well and good until some other method of that class assumes the method you inherit to behave a certain way, after all that is how the author of the original class designed it. You can partially protect against this by declaring all methods called by another of your methods private or non-virtual (final), unless they are designed to be overridden. Even this though isn't always good enough. Sometimes you might see something like this (in pseudo Java, hopefully readable to C++ and C# users)

interface UsefulThingsInterface {
    void doThings();
    void doMoreThings();
}

...

class WayOfDoingUsefulThings implements UsefulThingsInterface{
     private foo stuff;
     public final int getStuff();
     void doThings(){
       //modifies stuff, such that ...
       ...
     }
     ...
     void doMoreThings(){
       //ignores stuff
       ...
     }
 }

you think this is lovely, and have your own way of doing "things", but you use inheritance to acquire the ability to do "moreThings",

class MyUsefulThings extends WayOfDoingUsefulThings{
     void doThings {
        //my way
     }
}

And all is well and good. WayOfDoingUsefulThings was designed in such a way replacing one method doesn't change the semantics of any other...except wait, no it wasn't. It just looks like it was, but doThings changed mutable state that mattered so, even though it didn't call any override-able functions,

 void dealWithStuff(WayOfDoingUsefulThings bar){
     bar.doThings()
     use(bar.getStuff());
 }

now does something different than expected when you pass it a MyUsefulThings. Whats worse, you might not even know that WayOfDoingUsefulThings made those promises. Maybe dealWithStuff comes from the same library as WayOfDoingUsefulThings and getStuff() isn't even exported by the library (think of friend classes in C++). Worse still, you have defeated the static checks of the language without realizing it: dealWithStuff took a WayOfDoingUsefulThings just to make sure that it would have a getStuff() function that behaved a certain way.

Using composition

class MyUsefulThings implements UsefulThingsInterface{
     private way = new WayOfDoingUsefulThings()
     void doThings() {
        //my way
     }
     void doMoreThings() {
        this.way.doMoreThings();
     }
}

brings back static type safety. In general composition is easier to use and safer than inheritance when implementing subtyping. It also lets you override final methods which means that you should feel free to declare everything final/non-virtual except in interfaces the vast majority of the time.

In a better world languages would automatically insert the boilerplate with a delegation keyword. Most don't, so a downside is bigger classes. Although, you can get your IDE to write the delegating instance for you.

Now, life isn't just about polymorphism. You can don't need to subtype all the time. The goal of polymorphism is generally code reuse but it isn't the only way to achieve that goal. Often time, it makes sense to use composition, without subtype polymorphism, as a way of managing functionality.

Also, behavioral inheritance does have its uses. It is one of the most powerful ideas in computer science. Its just that, most of the time, good OOP applications can be written using only using interface inheritance and compositions. The two principles

  1. Ban inheritance or design for it
  2. Prefer composition

are a good guide for the reasons above, and don't incur any substantial costs.

share|improve this answer
    
Thanks for the detailed answer! –  illmath Feb 9 '12 at 9:11
    
Nice answer. I would summarize it that trying to achieve code reuse with inheritance is plain wrong path. Inheritance is very strong constraint (imho adding "power" is wrong analogy!) and creates strong dependency between inherited classes. Too many dependencies = bad code :) So inheritance (aka "behaves as") typically shines for unified interfaces (=hiding complexity of inherited classes), for anything else think twice or use composition... –  MaR Feb 9 '12 at 12:39

The example you've given is one where inheritance is the natural choice. I don't think anyone would claim that composition is always a better choice than inheritance -- it's just a guideline that means that it's often better to assemble several relatively simple objects than to create lots of highly specialized objects.

Delegation is one example of a way to use composition instead of inheritance. Delegation lets you modify the behavior of a class without subclassing. Consider a class that provides a network connection, NetStream. It might be natural to subclass NetStream to implement a common network protocol, so you might come up with FTPStream and HTTPStream. But instead of creating a very specific HTTPStream subclass for a single purpose, say, UpdateMyWebServiceHTTPStream, it's often better to use a plain old instance of HTTPStream along with a delegate that knows what to do with the data it receives from that object. One reason it's better is that it avoids a proliferation of classes that have to be maintained but which you'll never be able to reuse. Another reason is that the object that serves as the delegate can also be responsible for other things, such as managing the data received from the web service.

share|improve this answer

The reason people say this is that beginning OOP programmers, fresh out of their polymorphism-through-inheritance lectures, tend to write large classes with lots of polymorphic methods, and then somewhere down the road, they end up with an unmaintainable mess.

A typical example comes from the world of game development. Suppose you have a base class for all your game entities - the player's spaceship, monsters, bullets, etc.; each entity type has its own subclass. The inheritance approach would use a few polymorphic methods, e.g. update_controls(), update_physics(), draw(), etc., and implement them for each subclass. However, this means you're coupling unrelated functionality: it is irrelevant what an object looks like for moving it, and you don't need to know anything about its AI to draw it. The compositional approach instead defines several base classes (or interfaces), e.g. EntityBrain (subclasses implement AI or player input), EntityPhysics (subclasses implement movement physics) and EntityPainter (subclasses take care of drawing), and a non-polymorphic class Entity that holds one instance of each. This way, you can combine any appearance with any physics model and any AI, and since you keep them separate, your code will be much cleaner too. Also, problems such as "I want a monster that looks like the balloon monster in level 1, but behaves like the crazy clown in level 15" go away: you simply take the suitable components and glue them together.

Note that the compositional approach still uses inheritance within each component; although ideally you'd use just interfaces and their implementations here.

"Separation of concerns" is the key phrase here: representing physics, implementing an AI, and drawing an entity, are three concerns, combining them into an entity is a fourth. With the compositional approach, each concern is modelled as one class.

share|improve this answer
    
This is all good, and advocated in the article linked in the original question. I would love (whenever you get the time) if you could provide a simple example involving all of these entities, while also maintaining polymorphism (in C++). Or point me to a resource. Thanks. –  illmath Feb 10 '12 at 3:01

protected by gnat Aug 1 at 6:31

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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