Related
Is it a good concept to use multiple inheritance or can I do other things instead?
Multiple inheritance (abbreviated as MI) smells, which means that usually, it was done for bad reasons, and it will blow back in the face of the maintainer.
Summary
Consider composition of features, instead of inheritance
Be wary of the Diamond of Dread
Consider inheritance of multiple interfaces instead of objects
Sometimes, Multiple Inheritance is the right thing. If it is, then use it.
Be prepared to defend your multiple-inherited architecture in code reviews
1. Perhaps composition?
This is true for inheritance, and so, it's even more true for multiple inheritance.
Does your object really need to inherit from another? A Car does not need to inherit from an Engine to work, nor from a Wheel. A Car has an Engine and four Wheel.
If you use multiple inheritance to resolve these problems instead of composition, then you've done something wrong.
2. The Diamond of Dread
Usually, you have a class A, then B and C both inherit from A. And (don't ask me why) someone then decides that D must inherit both from B and C.
I've encountered this kind of problem twice in eight years, and it is amusing to see because of:
How much of a mistake it was from the beginning (In both cases, D should not have inherited from both B and C), because this was bad architecture (in fact, C should not have existed at all...)
How much maintainers were paying for that, because in C++, the parent class A was present twice in its grandchild class D, and thus, updating one parent field A::field meant either updating it twice (through B::field and C::field), or having something go silently wrong and crash, later (new a pointer in B::field, and delete C::field...)
Using the keyword virtual in C++ to qualify the inheritance avoids the double layout described above if this is not what you want, but anyway, in my experience, you're probably doing something wrong...
In Object hierarchy, you should try to keep the hierarchy as a Tree (a node has ONE parent), not as a graph.
More about the Diamond (edit 2017-05-03)
The real problem with the Diamond of Dread in C++ (assuming the design is sound - have your code reviewed!), is that you need to make a choice:
Is it desirable for the class A to exist twice in your layout, and what does it mean? If yes, then by all means inherit from it twice.
if it should exist only once, then inherit from it virtually.
This choice is inherent to the problem, and in C++, unlike other languages, you can actually do it without dogma forcing your design at language level.
But like all powers, with that power comes responsibility: Have your design reviewed.
3. Interfaces
Multiple inheritance of zero or one concrete classes, and zero or more interfaces is usually Okay, because you won't encounter the Diamond of Dread described above. In fact, this is how things are done in Java.
Usually, what you mean when C inherits from A and B is that users can use C as if it was an A, and/or as if it was a B.
In C++, an interface is an abstract class which has:
all its method declared pure virtual (suffixed by = 0) (removed the 2017-05-03)
no member variables
The Multiple inheritance of zero to one real object, and zero or more interfaces is not considered "smelly" (at least, not as much).
More about the C++ Abstract Interface (edit 2017-05-03)
First, the NVI pattern can be used to produce an interface, because the real criteria is to have no state (i.e. no member variables, except this). Your abstract interface's point is to publish a contract ("you can call me this way, and this way"), nothing more, nothing less. The limitation of having only abstract virtual methods should be a design choice, not an obligation.
Second, in C++, it makes sense to inherit virtually from abstract interfaces, (even with the additional cost/indirection). If you don't, and the interface inheritance appears multiple times in your hierarchy, then you'll have ambiguities.
Third, object orientation is great, but it is not The Only Truth Out ThereTM in C++. Use the right tools, and always remember you have other paradigms in C++ offering different kinds of solutions.
4. Do you really need Multiple Inheritance?
Sometimes, yes.
Usually, your C class is inheriting from A and B, and A and B are two unrelated objects (i.e. not in the same hierarchy, nothing in common, different concepts, etc.).
For example, you could have a system of Nodes with X,Y,Z coordinates, able to do a lot of geometric calculations (perhaps a point, part of geometric objects) and each Node is an Automated Agent, able to communicate with other agents.
Perhaps you already have access to two libraries, each with its own namespace (another reason to use namespaces... But you use namespaces, don't you?), one being geo and the other being ai
So you have your own own::Node derive both from ai::Agent and geo::Point.
This is the moment when you should ask yourself if you should not use composition instead. If own::Node is really really both a ai::Agent and a geo::Point, then composition will not do.
Then you'll need multiple inheritance, having your own::Node communicate with other agents according to their position in a 3D space.
(You'll note that ai::Agent and geo::Point are completely, totally, fully UNRELATED... This drastically reduces the danger of multiple inheritance)
Other cases (edit 2017-05-03)
There are other cases:
using (hopefully private) inheritance as implementation detail
some C++ idioms like policies could use multiple inheritance (when each part needs to communicate with the others through this)
the virtual inheritance from std::exception (Is Virtual Inheritance necessary for Exceptions?)
etc.
Sometimes you can use composition, and sometimes MI is better. The point is: You have a choice. Do it responsibly (and have your code reviewed).
5. So, should I do Multiple Inheritance?
Most of the time, in my experience, no. MI is not the right tool, even if it seems to work, because it can be used by the lazy to pile features together without realizing the consequences (like making a Car both an Engine and a Wheel).
But sometimes, yes. And at that time, nothing will work better than MI.
But because MI is smelly, be prepared to defend your architecture in code reviews (and defending it is a good thing, because if you're not able to defend it, then you should not do it).
From an interview with Bjarne Stroustrup:
People quite correctly say that you don't need multiple inheritance, because anything you can do with multiple inheritance you can also do with single inheritance. You just use the delegation trick I mentioned. Furthermore, you don't need any inheritance at all, because anything you do with single inheritance you can also do without inheritance by forwarding through a class. Actually, you don't need any classes either, because you can do it all with pointers and data structures. But why would you want to do that? When is it convenient to use the language facilities? When would you prefer a workaround? I've seen cases where multiple inheritance is useful, and I've even seen cases where quite complicated multiple inheritance is useful. Generally, I prefer to use the facilities offered by the language to doing workarounds
There's no reason to avoid it and it can be very useful in situations. You need to be aware of the potential issues though.
The biggest one being the diamond of death:
class GrandParent;
class Parent1 : public GrandParent;
class Parent2 : public GrandParent;
class Child : public Parent1, public Parent2;
You now have two "copies" of GrandParent within Child.
C++ has thought of this though and lets you do virtual inheritence to get around the issues.
class GrandParent;
class Parent1 : public virtual GrandParent;
class Parent2 : public virtual GrandParent;
class Child : public Parent1, public Parent2;
Always review your design, ensure you are not using inheritance to save on data reuse. If you can represent the same thing with composition (and typically you can) this is a far better approach.
See w:Multiple Inheritance.
Multiple inheritance has received
criticism and as such, is not
implemented in many languages.
Criticisms includes:
Increased complexity
Semantic ambiguity often summarized as the diamond
problem.
Not being able to explicitly inherit multiple times from a single
class
Order of inheritance changing class semantics.
Multiple inheritance in languages with
C++/Java style constructors
exacerbates the inheritance problem of
constructors and constructor chaining,
thereby creating maintenance and
extensibility problems in these
languages. Objects in inheritance
relationships with greatly varying
construction methods are hard to
implement under the constructor
chaining paradigm.
Modern way of resolving this to use interface (pure abstract class) like COM and Java interface.
I can do other things in place of this?
Yes, you can. I am going to steal from GoF.
Program to an Interface, not an Implementation
Prefer composition over inheritance
Public inheritance is an IS-A relationship, and sometimes a class will be an type of several different classes, and sometimes it's important to reflect this.
"Mixins" are also sometimes useful. They are generally small classes, usually not inheriting from anything, providing useful functionality.
As long as the inheritance hierarchy is fairly shallow (as it should almost always be), and well managed, you're unlikely to get the dreaded diamond inheritance. The diamond isn't a problem with all languages that use multiple inheritance, but C++'s treatment of it is frequently awkward and sometimes puzzling.
While I've run into cases where multiple inheritance is very handy, they're actually fairly rare. This is likely because I prefer to use other design methods when I don't really need multiple inheritance. I do prefer to avoid confusing language constructs, and it's easy to construct inheritance cases where you have to read the manual really well to figure out what's going on.
You shouldn't "avoid" multiple inheritance but you should be aware of problems that can arise such as the 'diamond problem' ( http://en.wikipedia.org/wiki/Diamond_problem ) and treat the power given to you with care, as you should with all powers.
At the risk of getting a bit abstract, I find it illuminating to think about inheritance within the frame of category theory.
If we think of all our classes and arrows between them denoting inheritance relations, then something like this
A --> B
means that class B derives from class A. Note that, given
A --> B, B --> C
we say C derives from B which derives from A, so C is also said to derive from A, thus
A --> C
Furthermore, we say that for every class A that trivially A derives from A, thus our inheritance model fulfills the definition of a category. In more traditional language, we have a category Class with objects all classes and morphisms the inheritance relations.
That's a bit of setup, but with that let's take a look at our Diamond of Doom:
C --> D
^ ^
| |
A --> B
It's a shady looking diagram, but it'll do. So D inherits from all of A, B, and C. Furthermore, and getting closer to addressing OP's question, D also inherits from any superclass of A. We can draw a diagram
C --> D --> R
^ ^
| |
A --> B
^
|
Q
Now, problems associated with the Diamond of Death here are when C and B share some property/method names and things get ambiguous; however, if we move any shared behavior into A then the ambiguity disappears.
Put in categorical terms, we want A, B and C to be such that if B and C inherit from Q then A can be rewritten as as subclass of Q. This makes A something called a pushout.
There is also a symmetric construction on D called a pullback. This is essentially the most general useful class you can construct which inherits from both B and C. That is, if you have any other class R multiply inheriting from B and C, then D is a class where R can be rewritten as as subclass of D.
Making sure your tips of the diamond are pullbacks and pushouts gives us a nice way to generically handle name-clashing or maintenance issues which might arise otherwise.
Note Paercebal's answer inspired this as his admonitions are implied by the above model given that we work in the full category Class of all possible classes.
I wanted to generalize his argument to something which shows how complicated multiple inheritance relationships can be both powerful and non-problematic.
TL;DR Think of the inheritance relationships in your program as forming a category. Then you can avoid Diamond of Doom problems by making multiply-inherited classes pushouts and symmetrically, making a common parent class which is a pullback.
We use Eiffel. We have excellent MI. No worries. No issues. Easily managed. There are times to NOT use MI. However, it useful more than people realize because they are: A) in a dangerous language that does not manage it well -OR- B) satisfied with how they've worked around MI for years and years -OR- C) other reasons (too numerous to list I am quite sure--see answers above).
For us, using Eiffel, MI is as natural as anything else and another fine tool in the toolbox. Frankly, we're quite unconcerned that no one else is using Eiffel. No worries. We are happy with what we have and invite you to have a look.
While you're looking: Take special note of Void-safety and the eradication of Null pointer dereferencing. While we're all dancing around MI, your pointers are getting lost! :-)
You should use it carefully, there are some cases, like the Diamond Problem, when things can go complicated.
(source: learncpp.com)
Every programming language has a slightly different treatment of object-oriented programming with pros and cons. C++'s version places the emphasis squarely on performance and has the accompanying downside that it is disturbingly easy to write invalid code - and this is true of multiple inheritance. As a consequence there is a tendency to steer programmers away from this feature.
Other people have addressed the question of what multiple inheritance isn't good for. But we have seen quite a few comments that more-or-less imply that the reason to avoid it is because it's not safe. Well, yes and no.
As is often true in C++, if you follow a basic guideline you can use it safely without having to "look over your shoulder" constantly. The key idea is that you distinguish a special kind of class definition called a "mix-in"; class is a mix-in if all its member functions are virtual (or pure virtual). Then you are allowed to inherit from a single main class and as many "mix-ins" as you like - but you should inherit mixins with the keyword "virtual". e.g.
class CounterMixin {
int count;
public:
CounterMixin() : count( 0 ) {}
virtual ~CounterMixin() {}
virtual void increment() { count += 1; }
virtual int getCount() { return count; }
};
class Foo : public Bar, virtual public CounterMixin { ..... };
My suggestion is that if you intend to use a class as a mix-in class you also adopt a naming convention to make it easy for anyone reading the code to see what's happening & to verify you're playing by the rules of the basic guideline. And you'll find it works much better if your mix-ins have default constructors too, just because of the way virtual base classes work. And remember to make all the destructors virtual too.
Note that my use of the word "mix-in" here isn't the same as the parameterised template class (see this link for a good explanation) but I think it is a fair use of the terminology.
Now I don't want to give the impression that this is the only way to use multiple inheritance safely. It's just one way that is fairly easy to check.
Uses and Abuses of Inheritance.
The article does a great job of explaining inheritance, and it's dangers.
Beyond the diamond pattern, multiple inheritance tends to make the object model harder to understand, which in turn increases maintenance costs.
Composition is intrinsically easy to understand, comprehend, and explain. It can get tedious to write code for, but a good IDE (it's been a few years since I've worked with Visual Studio, but certainly the Java IDEs all have great composition shortcut automating tools) should get you over that hurdle.
Also, in terms of maintenance, the "diamond problem" comes up in non-literal inheritance instances as well. For instance, if you have A and B and your class C extends them both, and A has a 'makeJuice' method which makes orange juice and you extend that to make orange juice with a twist of lime: what happens when the designer for 'B' adds a 'makeJuice' method which generates and electrical current? 'A' and 'B' may be compatible "parents" right now, but that doesn't mean they will always be so!
Overall, the maxim of tending to avoid inheritance, and especially multiple inheritance, is sound. As all maxims, there are exceptions, but you need to make sure that there is a flashing green neon sign pointing at any exceptions you code (and train your brain so that any time you see such inheritance trees you draw in your own flashing green neon sign), and that you check to make sure it all makes sense every once in a while.
The key issue with MI of concrete objects is that rarely do you have an object that legitimately should "Be an A AND be a B", so it is rarely the correct solution on logical grounds. Far more often, you have an object C that obeys "C can act as an A or a B", which you can achieve via interface inheritance & composition. But make no mistake- inheritance of multiple interfaces is still MI, just a subset of it.
For C++ in particular, the key weakness of the feature isn't the actual EXISTENCE of Multiple Inheritance, but some constructs it allows that are almost always malformed. For example, inheriting multiple copies of the same object like:
class B : public A, public A {};
is malformed BY DEFINITION. Translated into English this is "B is an A and an A". So, even in human language there's a severe ambiguity. Did you mean "B has 2 As" or just "B is an A"?. Allowing such pathological code, and worse making it a usage example, did C++ no favors when it came to making a case for keeping the feature in successor languages.
You can use composition in preference to inheritance.
The general feeling is that composition is better, and it's very well discussed.
it takes 4/8 bytes per class involved.
(One this pointer per class).
This might never be a concern, but if one day you have a micro data structure which is instanced billions of time it will be.
Why prefer composition over inheritance? What trade-offs are there for each approach? When should you choose inheritance over composition?
Prefer composition over inheritance as it is more malleable / easy to modify later, but do not use a compose-always approach. With composition, it's easy to change behavior on the fly with Dependency Injection / Setters. Inheritance is more rigid as most languages do not allow you to derive from more than one type. So the goose is more or less cooked once you derive from TypeA.
My acid test for the above is:
Does TypeB want to expose the complete interface (all public methods no less) of TypeA such that TypeB can be used where TypeA is expected? Indicates Inheritance.
e.g. A Cessna biplane will expose the complete interface of an airplane, if not more. So that makes it fit to derive from Airplane.
Does TypeB want only some/part of the behavior exposed by TypeA? Indicates need for Composition.
e.g. A Bird may need only the fly behavior of an Airplane. In this case, it makes sense to extract it out as an interface / class / both and make it a member of both classes.
Update: Just came back to my answer and it seems now that it is incomplete without a specific mention of Barbara Liskov's Liskov Substitution Principle as a test for 'Should I be inheriting from this type?'
Think of containment as a has a relationship. A car "has an" engine, a person "has a" name, etc.
Think of inheritance as an is a relationship. A car "is a" vehicle, a person "is a" mammal, etc.
I take no credit for this approach. I took it straight from the Second Edition of Code Complete by Steve McConnell, Section 6.3.
If you understand the difference, it's easier to explain.
Procedural Code
An example of this is PHP without the use of classes (particularly before PHP5). All logic is encoded in a set of functions. You may include other files containing helper functions and so on and conduct your business logic by passing data around in functions. This can be very hard to manage as the application grows. PHP5 tries to remedy this by offering a more object-oriented design.
Inheritance
This encourages the use of classes. Inheritance is one of the three tenets of OO design (inheritance, polymorphism, encapsulation).
class Person {
String Title;
String Name;
Int Age
}
class Employee : Person {
Int Salary;
String Title;
}
This is inheritance at work. The Employee "is a" Person or inherits from Person. All inheritance relationships are "is-a" relationships. Employee also shadows the Title property from Person, meaning Employee.Title will return the Title for the Employee and not the Person.
Composition
Composition is favoured over inheritance. To put it very simply you would have:
class Person {
String Title;
String Name;
Int Age;
public Person(String title, String name, String age) {
this.Title = title;
this.Name = name;
this.Age = age;
}
}
class Employee {
Int Salary;
private Person person;
public Employee(Person p, Int salary) {
this.person = p;
this.Salary = salary;
}
}
Person johnny = new Person ("Mr.", "John", 25);
Employee john = new Employee (johnny, 50000);
Composition is typically "has a" or "uses a" relationship. Here the Employee class has a Person. It does not inherit from Person but instead gets the Person object passed to it, which is why it "has a" Person.
Composition over Inheritance
Now say you want to create a Manager type so you end up with:
class Manager : Person, Employee {
...
}
This example will work fine, however, what if Person and Employee both declared Title? Should Manager.Title return "Manager of Operations" or "Mr."? Under composition this ambiguity is better handled:
Class Manager {
public string Title;
public Manager(Person p, Employee e)
{
this.Title = e.Title;
}
}
The Manager object is composed of an Employee and a Person. The Title behaviour is taken from Employee. This explicit composition removes ambiguity among other things and you'll encounter fewer bugs.
With all the undeniable benefits provided by inheritance, here's some of its disadvantages.
Disadvantages of Inheritance:
You can't change the implementation inherited from super classes at runtime (obviously because inheritance is defined at compile time).
Inheritance exposes a subclass to details of its parent class implementation, that's why it's often said that inheritance breaks encapsulation (in a sense that you really need to focus on interfaces only not implementation, so reusing by sub classing is not always preferred).
The tight coupling provided by inheritance makes the implementation of a subclass very bound up with the implementation of a super class that any change in the parent implementation will force the sub class to change.
Excessive reusing by sub-classing can make the inheritance stack very deep and very confusing too.
On the other hand Object composition is defined at runtime through objects acquiring references to other objects. In such a case these objects will never be able to reach each-other's protected data (no encapsulation break) and will be forced to respect each other's interface. And in this case also, implementation dependencies will be a lot less than in case of inheritance.
Another, very pragmatic reason, to prefer composition over inheritance has to do with your domain model, and mapping it to a relational database. It's really hard to map inheritance to the SQL model (you end up with all sorts of hacky workarounds, like creating columns that aren't always used, using views, etc). Some ORMLs try to deal with this, but it always gets complicated quickly. Composition can be easily modeled through a foreign-key relationship between two tables, but inheritance is much harder.
While in short words I would agree with "Prefer composition over inheritance", very often for me it sounds like "prefer potatoes over coca-cola". There are places for inheritance and places for composition. You need to understand difference, then this question will disappear. What it really means for me is "if you are going to use inheritance - think again, chances are you need composition".
You should prefer potatoes over coca cola when you want to eat, and coca cola over potatoes when you want to drink.
Creating a subclass should mean more than just a convenient way to call superclass methods. You should use inheritance when subclass "is-a" super class both structurally and functionally, when it can be used as superclass and you are going to use that. If it is not the case - it is not inheritance, but something else. Composition is when your objects consists of another, or has some relationship to them.
So for me it looks like if someone does not know if he needs inheritance or composition, the real problem is that he does not know if he want to drink or to eat. Think about your problem domain more, understand it better.
Didn't find a satisfactory answer here, so I wrote a new one.
To understand why "prefer composition over inheritance", we need first get back the assumption omitted in this shortened idiom.
There are two benefits of inheritance: subtyping and subclassing
Subtyping means conforming to a type (interface) signature, i.e. a set of APIs, and one can override part of the signature to achieve subtyping polymorphism.
Subclassing means implicit reuse of method implementations.
With the two benefits comes two different purposes for doing inheritance: subtyping oriented and code reuse oriented.
If code reuse is the sole purpose, subclassing may give one more than what he needs, i.e. some public methods of the parent class don't make much sense for the child class. In this case, instead of favoring composition over inheritance, composition is demanded. This is also where the "is-a" vs. "has-a" notion comes from.
So only when subtyping is purposed, i.e. to use the new class later in a polymorphic manner, do we face the problem of choosing inheritance or composition. This is the assumption that gets omitted in the shortened idiom under discussion.
To subtype is to conform to a type signature, this means composition has always to expose no less amount of APIs of the type. Now the trade offs kick in:
Inheritance provides straightforward code reuse if not overridden, while composition has to re-code every API, even if it's just a simple job of delegation.
Inheritance provides straightforward open recursion via the internal polymorphic site this, i.e. invoking overriding method (or even type) in another member function, either public or private (though discouraged). Open recursion can be simulated via composition, but it requires extra effort and may not always viable(?). This answer to a duplicated question talks something similar.
Inheritance exposes protected members. This breaks encapsulation of the parent class, and if used by subclass, another dependency between the child and its parent is introduced.
Composition has the befit of inversion of control, and its dependency can be injected dynamically, as is shown in decorator pattern and proxy pattern.
Composition has the benefit of combinator-oriented programming, i.e. working in a way like the composite pattern.
Composition immediately follows programming to an interface.
Composition has the benefit of easy multiple inheritance.
With the above trade offs in mind, we hence prefer composition over inheritance. Yet for tightly related classes, i.e. when implicit code reuse really make benefits, or the magic power of open recursion is desired, inheritance shall be the choice.
Inheritance is pretty enticing especially coming from procedural-land and it often looks deceptively elegant. I mean all I need to do is add this one bit of functionality to some other class, right? Well, one of the problems is that inheritance is probably the worst form of coupling you can have
Your base class breaks encapsulation by exposing implementation details to subclasses in the form of protected members. This makes your system rigid and fragile. The more tragic flaw however is the new subclass brings with it all the baggage and opinion of the inheritance chain.
The article, Inheritance is Evil: The Epic Fail of the DataAnnotationsModelBinder, walks through an example of this in C#. It shows the use of inheritance when composition should have been used and how it could be refactored.
When can you use composition?
You can always use composition. In some cases, inheritance is also possible and may lead to a more powerful and/or intuitive API, but composition is always an option.
When can you use inheritance?
It is often said that if "a bar is a foo", then the class Bar can inherit the class Foo. Unfortunately, this test alone is not reliable, use the following instead:
a bar is a foo, AND
bars can do everything that foos can do.
The first test ensures that all getters of Foo make sense in Bar (= shared properties), while the second test makes sure that all setters of Foo make sense in Bar (= shared functionality).
Example: Dog/Animal
A dog is an animal AND dogs can do everything that animals can do (such as breathing, moving, etc.). Therefore, the class Dog can inherit the class Animal.
Counter-example: Circle/Ellipse
A circle is an ellipse BUT circles can't do everything that ellipses can do. For example, circles can't stretch, while ellipses can. Therefore, the class Circle cannot inherit the class Ellipse.
This is called the Circle-Ellipse problem, which isn't really a problem, but more an indication that "a bar is a foo" isn't a reliable test by itself. In particular, this example highlights that derived classes should extend the functionality of base classes, never restrict it. Otherwise, the base class couldn't be used polymorphically. Adding the test "bars can do everything that foos can do" ensures that polymorphic use is possible, and is equivalent to the Liskov Substitution Principle:
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
When should you use inheritance?
Even if you can use inheritance doesn't mean you should: using composition is always an option. Inheritance is a powerful tool allowing implicit code reuse and dynamic dispatch, but it does come with a few disadvantages, which is why composition is often preferred. The trade-offs between inheritance and composition aren't obvious, and in my opinion are best explained in lcn's answer.
As a rule of thumb, I tend to choose inheritance over composition when polymorphic use is expected to be very common, in which case the power of dynamic dispatch can lead to a much more readable and elegant API. For example, having a polymorphic class Widget in GUI frameworks, or a polymorphic class Node in XML libraries allows to have an API which is much more readable and intuitive to use than what you would have with a solution purely based on composition.
In Java or C#, an object cannot change its type once it has been instantiated.
So, if your object need to appear as a different object or behave differently depending on an object state or conditions, then use Composition: Refer to State and Strategy Design Patterns.
If the object need to be of the same type, then use Inheritance or implement interfaces.
Personally I learned to always prefer composition over inheritance. There is no programmatic problem you can solve with inheritance which you cannot solve with composition; though you may have to use Interfaces(Java) or Protocols(Obj-C) in some cases. Since C++ doesn't know any such thing, you'll have to use abstract base classes, which means you cannot get entirely rid of inheritance in C++.
Composition is often more logical, it provides better abstraction, better encapsulation, better code reuse (especially in very large projects) and is less likely to break anything at a distance just because you made an isolated change anywhere in your code. It also makes it easier to uphold the "Single Responsibility Principle", which is often summarized as "There should never be more than one reason for a class to change.", and it means that every class exists for a specific purpose and it should only have methods that are directly related to its purpose. Also having a very shallow inheritance tree makes it much easier to keep the overview even when your project starts to get really large. Many people think that inheritance represents our real world pretty well, but that isn't the truth. The real world uses much more composition than inheritance. Pretty much every real world object you can hold in your hand has been composed out of other, smaller real world objects.
There are downsides of composition, though. If you skip inheritance altogether and only focus on composition, you will notice that you often have to write a couple of extra code lines that weren't necessary if you had used inheritance. You are also sometimes forced to repeat yourself and this violates the DRY Principle (DRY = Don't Repeat Yourself). Also composition often requires delegation, and a method is just calling another method of another object with no other code surrounding this call. Such "double method calls" (which may easily extend to triple or quadruple method calls and even farther than that) have much worse performance than inheritance, where you simply inherit a method of your parent. Calling an inherited method may be equally fast as calling a non-inherited one, or it may be slightly slower, but is usually still faster than two consecutive method calls.
You may have noticed that most OO languages don't allow multiple inheritance. While there are a couple of cases where multiple inheritance can really buy you something, but those are rather exceptions than the rule. Whenever you run into a situation where you think "multiple inheritance would be a really cool feature to solve this problem", you are usually at a point where you should re-think inheritance altogether, since even it may require a couple of extra code lines, a solution based on composition will usually turn out to be much more elegant, flexible and future proof.
Inheritance is really a cool feature, but I'm afraid it has been overused the last couple of years. People treated inheritance as the one hammer that can nail it all, regardless if it was actually a nail, a screw, or maybe a something completely different.
My general rule of thumb: Before using inheritance, consider if composition makes more sense.
Reason: Subclassing usually means more complexity and connectedness, i.e. harder to change, maintain, and scale without making mistakes.
A much more complete and concrete answer from Tim Boudreau of Sun:
Common problems to the use of inheritance as I see it are:
Innocent acts can have unexpected results - The classic example of this is calls to overridable methods from the superclass
constructor, before the subclasses instance fields have been
initialized. In a perfect world, nobody would ever do that. This is
not a perfect world.
It offers perverse temptations for subclassers to make assumptions about order of method calls and such - such assumptions tend not to
be stable if the superclass may evolve over time. See also my toaster
and coffee pot analogy.
Classes get heavier - you don't necessarily know what work your superclass is doing in its constructor, or how much memory it's going
to use. So constructing some innocent would-be lightweight object can
be far more expensive than you think, and this may change over time if
the superclass evolves
It encourages an explosion of subclasses. Classloading costs time, more classes costs memory. This may be a non-issue until you're
dealing with an app on the scale of NetBeans, but there, we had real
issues with, for example, menus being slow because the first display
of a menu triggered massive class loading. We fixed this by moving to
more declarative syntax and other techniques, but that cost time to
fix as well.
It makes it harder to change things later - if you've made a class public, swapping the superclass is going to break subclasses -
it's a choice which, once you've made the code public, you're married
to. So if you're not altering the real functionality to your
superclass, you get much more freedom to change things later if you
use, rather than extend the thing you need. Take, for example,
subclassing JPanel - this is usually wrong; and if the subclass is
public somewhere, you never get a chance to revisit that decision. If
it's accessed as JComponent getThePanel() , you can still do it (hint:
expose models for the components within as your API).
Object hierarchies don't scale (or making them scale later is much harder than planning ahead) - this is the classic "too many layers"
problem. I'll go into this below, and how the AskTheOracle pattern can
solve it (though it may offend OOP purists).
...
My take on what to do, if you do allow for inheritance, which you may
take with a grain of salt is:
Expose no fields, ever, except constants
Methods shall be either abstract or final
Call no methods from the superclass constructor
...
all of this applies less to small projects than large ones, and less
to private classes than public ones
Inheritance is very powerful, but you can't force it (see: the circle-ellipse problem). If you really can't be completely sure of a true "is-a" subtype relationship, then it's best to go with composition.
Inheritance creates a strong relationship between a subclass and super class; subclass must be aware of super class'es implementation details. Creating the super class is much harder, when you have to think about how it can be extended. You have to document class invariants carefully, and state what other methods overridable methods use internally.
Inheritance is sometimes useful, if the hierarchy really represents a is-a-relationship. It relates to Open-Closed Principle, which states that classes should be closed for modification but open to extension. That way you can have polymorphism; to have a generic method that deals with super type and its methods, but via dynamic dispatch the method of subclass is invoked. This is flexible, and helps to create indirection, which is essential in software (to know less about implementation details).
Inheritance is easily overused, though, and creates additional complexity, with hard dependencies between classes. Also understanding what happens during execution of a program gets pretty hard due to layers and dynamic selection of method calls.
I would suggest using composing as the default. It is more modular, and gives the benefit of late binding (you can change the component dynamically). Also it's easier to test the things separately. And if you need to use a method from a class, you are not forced to be of certain form (Liskov Substitution Principle).
Suppose an aircraft has only two parts: an engine and wings.
Then there are two ways to design an aircraft class.
Class Aircraft extends Engine{
var wings;
}
Now your aircraft can start with having fixed wings
and change them to rotary wings on the fly. It's essentially
an engine with wings. But what if I wanted to change
the engine on the fly as well?
Either the base class Engine exposes a mutator to change its
properties, or I redesign Aircraft as:
Class Aircraft {
var wings;
var engine;
}
Now, I can replace my engine on the fly as well.
If you want the canonical, textbook answer people have been giving since the rise of OOP (which you see many people giving in these answers), then apply the following rule: "if you have an is-a relationship, use inheritance. If you have a has-a relationship, use composition".
This is the traditional advice, and if that satisfies you, you can stop reading here and go on your merry way. For everyone else...
is-a/has-a comparisons have problems
For example:
A square is-a rectangle, but if your rectangle class has setWidth()/setHeight() methods, then there's no reasonable way to make a Square inherit from Rectangle without breaking Liskov's substitution principle.
An is-a relationship can often be rephrased to sound like a has-a relationship. For example, an employee is-a person, but a person also has-an employment status of "employed".
is-a relationships can lead to nasty multiple inheritance hierarchies if you're not careful. After all, there's no rule in English that states that an object is exactly one thing.
People are quick to pass this "rule" around, but has anyone ever tried to back it up, or explain why it's a good heuristic to follow? Sure, it fits nicely into the idea that OOP is supposed to model the real world, but that's not in-and-of-itself a reason to adopt a principle.
See this StackOverflow question for more reading on this subject.
To know when to use inheritance vs composition, we first need to understand the pros and cons of each.
The problems with implementation inheritance
Other answers have done a wonderful job at explaining the issues with inheritance, so I'll try to not delve into too many details here. But, here's a brief list:
It can be difficult to follow a logic that weaves between base and sub-class methods.
Carelessly implementing one method in your class by calling another overridable method will cause you to leak implementation details and break encapsulation, as the end-user could override your method and detect when you internally call it. (See "Effective Java" item 18).
The fragile base problem, which simply states that your end-user's code will break if they happen to depend on the leakage of implementation details when you attempt to change them. To make matters worse, most OOP languages allow inheritance by default - API designers who aren't proactively preventing people from inheriting from their public classes need to be extra cautious whenever they refactor their base classes. Unfortunately, the fragile base problem is often misunderstood, causing many to not understand what it takes to maintain a class that anyone can inherit from.
The deadly diamond of death
The problems with composition
It can sometimes be a little verbose.
That's it. I'm serious. This is still a real issue and can sometimes create conflict with the DRY principle, but it's generally not that bad, at least compared to the myriad of pitfalls associated with inheritance.
When should inheritance be used?
Next time you're drawing out your fancy UML diagrams for a project (if you do that), and you're thinking about adding in some inheritance, please adhere to the following advice: don't.
At least, not yet.
Inheritance is sold as a tool to achieve polymorphism, but bundled with it is this powerful code-reuse system, that frankly, most code doesn't need. The problem is, as soon as you publicly expose your inheritance hierarchy, you're locked into this particular style of code-reuse, even if it's overkill to solve your particular problem.
To avoid this, my two cents would be to never expose your base classes publicly.
If you need polymorphism, use an interface.
If you need to allow people to customize the behavior of your class, provide explicit hook-in points via the strategy pattern, it's a more readable way to accomplish this, plus, it's easier to keep this sort of API stable as you're in full control over what behaviors they can and can not change.
If you're trying to follow the open-closed principle by using inheritance to avoid adding a much-needed update to a class, just don't. Update the class. Your codebase will be much cleaner if you actually take ownership of the code you're hired to maintain instead of trying to tack stuff onto the side of it. If you're scared about introducing bugs, then get the existing code under test.
If you need to reuse code, start out by trying to use composition or helper functions.
Finally, if you've decided that there's no other good option, and you must use inheritance to achieve the code-reuse that you need, then you can use it, but, follow these four P.A.I.L. rules of restricted inheritance to keep it sane.
Use inheritance as a private implementation detail. Don't expose your base class publicly, use interfaces for that. This lets you freely add or remove inheritance as you see fit without making a breaking change.
Keep your base class abstract. It makes it easier to divide out the logic that needs to be shared from the logic that doesn't.
Isolate your base and child classes. Don't let your subclass override base class methods (use the strategy pattern for that), and avoid having them expect properties/methods to exist on each other, use other forms of code-sharing to achieve that. Use appropriate language features to force all methods on the base class to be non-overridable ("final" in Java, or non-virtual in C#).
Inheritance is a last resort.
The Isolate rule in particular may sound a little rough to follow, but if you discipline yourself, you'll get some pretty nice benefits. In particular, it gives you the freedom to avoid all of the main nasty pitfalls associated with the inheritance that were mentioned above.
It's much easier to follow the code because it doesn't weave in and out of base/sub classes.
You can not accidentally leak when your methods are internally calling other overridable methods if you never make any of your methods overridable. In other words, you won't accidentally break encapsulation.
The fragile base class problem stems from the ability to depend on accidentally leaked implementation details. Since the base class is now isolated, it will be no more fragile than a class depending on another via composition.
The deadly diamond of death isn't an issue anymore, since there's simply no need to have multiple layers of inheritance. If you have the abstract base classes B and C, which both share a lot of functionality, just move that functionality out of B and C and into a new abstract base class, class D. Anyone who inherited from B should update to inherit from both B and D, and anyone who inherited from C should inherit from C and D. Since your base classes are all private implementation details, it shouldn't be too difficult to figure out who's inheriting from what, to make these changes.
Conclusion
My primary suggestion would be to use your brain on this matter. What's far more important than a list of dos and don'ts about when to use inheritance is an intuitive understanding of inheritance and its associated pros and cons, along with a good understanding of the other tools out there that can be used instead of inheritance (composition isn't the only alternative. For example, the strategy pattern is an amazing tool that's forgotten far too often). Perhaps when you have a good, solid understanding of all of these tools, you'll choose to use inheritance more often than I would recommend, and that's completely fine. At least, you're making an informed decision, and aren't just using inheritance because that's the only way you know how to do it.
Further reading:
An article I wrote on this subject, that dives even deeper and provides examples.
A webpage talking about three different jobs that inheritance does, and how those jobs can be done via other means in the Go language.
A list of reasons why it can be good to declare your class as non-inheritable (e.g. "final" in Java).
The "Effective Java" book by Joshua Bloch, item 18, which discusses composition over inheritance, and some of the dangers of inheritance.
You need to have a look at The Liskov Substitution Principle in Uncle Bob's SOLID principles of class design. :)
To address this question from a different perspective for newer programmers:
Inheritance is often taught early when we learn object-oriented programming, so it's seen as an easy solution to a common problem.
I have three classes that all need some common functionality. So if I
write a base class and have them all inherit from it, then they will
all have that functionality and I'll only need to maintain it in once
place.
It sounds great, but in practice it almost never, ever works, for one of several reasons:
We discover that there are some other functions that we want our classes to have. If the way that we add functionality to classes is through inheritance, we have to decide - do we add it to the existing base class, even though not every class that inherits from it needs that functionality? Do we create another base class? But what about classes that already inherit from the other base class?
We discover that for just one of the classes that inherits from our base class we want the base class to behave a little differently. So now we go back and tinker with our base class, maybe adding some virtual methods, or even worse, some code that says, "If I'm inherited type A, do this, but if I'm inherited type B, do that." That's bad for lots of reasons. One is that every time we change the base class, we're effectively changing every inherited class. So we're really changing class A, B, C, and D because we need a slightly different behavior in class A. As careful as we think we are, we might break one of those classes for reasons that have nothing to do with those classes.
We might know why we decided to make all of these classes inherit from each other, but it might not (probably won't) make sense to someone else who has to maintain our code. We might force them into a difficult choice - do I do something really ugly and messy to make the change I need (see the previous bullet point) or do I just rewrite a bunch of this.
In the end, we tie our code in some difficult knots and get no benefit whatsoever from it except that we get to say, "Cool, I learned about inheritance and now I used it." That's not meant to be condescending because we've all done it. But we all did it because no one told us not to.
As soon as someone explained "favor composition over inheritance" to me, I thought back over every time I tried to share functionality between classes using inheritance and realized that most of the time it didn't really work well.
The antidote is the Single Responsibility Principle. Think of it as a constraint. My class must do one thing. I must be able to give my class a name that somehow describes that one thing it does. (There are exceptions to everything, but absolute rules are sometimes better when we're learning.) It follows that I cannot write a base class called ObjectBaseThatContainsVariousFunctionsNeededByDifferentClasses. Whatever distinct functionality I need must be in its own class, and then other classes that need that functionality can depend on that class, not inherit from it.
At the risk of oversimplifying, that's composition - composing multiple classes to work together. And once we form that habit we find that it's much more flexible, maintainable, and testable than using inheritance.
When you want to "copy"/Expose the base class' API, you use inheritance. When you only want to "copy" functionality, use delegation.
One example of this: You want to create a Stack out of a List. Stack only has pop, push and peek. You shouldn't use inheritance given that you don't want push_back, push_front, removeAt, et al.-kind of functionality in a Stack.
These two ways can live together just fine and actually support each other.
Composition is just playing it modular: you create interface similar to the parent class, create new object and delegate calls to it. If these objects need not to know of each other, it's quite safe and easy to use composition. There are so many possibilites here.
However, if the parent class for some reason needs to access functions provided by the "child class" for inexperienced programmer it may look like it's a great place to use inheritance. The parent class can just call it's own abstract "foo()" which is overwritten by the subclass and then it can give the value to the abstract base.
It looks like a nice idea, but in many cases it's better just give the class an object which implements the foo() (or even set the value provided the foo() manually) than to inherit the new class from some base class which requires the function foo() to be specified.
Why?
Because inheritance is a poor way of moving information.
The composition has a real edge here: the relationship can be reversed: the "parent class" or "abstract worker" can aggregate any specific "child" objects implementing certain interface + any child can be set inside any other type of parent, which accepts it's type. And there can be any number of objects, for example MergeSort or QuickSort could sort any list of objects implementing an abstract Compare -interface. Or to put it another way: any group of objects which implement "foo()" and other group of objects which can make use of objects having "foo()" can play together.
I can think of three real reasons for using inheritance:
You have many classes with same interface and you want to save time writing them
You have to use same Base Class for each object
You need to modify the private variables, which can not be public in any case
If these are true, then it is probably necessary to use inheritance.
There is nothing bad in using reason 1, it is very good thing to have a solid interface on your objects. This can be done using composition or with inheritance, no problem - if this interface is simple and does not change. Usually inheritance is quite effective here.
If the reason is number 2 it gets a bit tricky. Do you really only need to use the same base class? In general, just using the same base class is not good enough, but it may be a requirement of your framework, a design consideration which can not be avoided.
However, if you want to use the private variables, the case 3, then you may be in trouble. If you consider global variables unsafe, then you should consider using inheritance to get access to private variables also unsafe. Mind you, global variables are not all THAT bad - databases are essentially big set of global variables. But if you can handle it, then it's quite fine.
Aside from is a/has a considerations, one must also consider the "depth" of inheritance your object has to go through. Anything beyond five or six levels of inheritance deep might cause unexpected casting and boxing/unboxing problems, and in those cases it might be wise to compose your object instead.
When you have an is-a relation between two classes (example dog is a canine), you go for inheritance.
On the other hand when you have has-a or some adjective relationship between two classes (student has courses) or (teacher studies courses), you chose composition.
A simple way to make sense of this would be that inheritance should be used when you need an object of your class to have the same interface as its parent class, so that it can thereby be treated as an object of the parent class (upcasting). Moreover, function calls on a derived class object would remain the same everywhere in code, but the specific method to call would be determined at runtime (i.e. the low-level implementation differs, the high-level interface remains the same).
Composition should be used when you do not need the new class to have the same interface, i.e. you wish to conceal certain aspects of the class' implementation which the user of that class need not know about. So composition is more in the way of supporting encapsulation (i.e. concealing the implementation) while inheritance is meant to support abstraction (i.e. providing a simplified representation of something, in this case the same interface for a range of types with different internals).
Subtyping is appropriate and more powerful where the invariants can be enumerated, else use function composition for extensibility.
I agree with #Pavel, when he says, there are places for composition and there are places for inheritance.
I think inheritance should be used if your answer is an affirmative to any of these questions.
Is your class part of a structure that benefits from polymorphism ? For example, if you had a Shape class, which declares a method called draw(), then we clearly need Circle and Square classes to be subclasses of Shape, so that their client classes would depend on Shape and not on specific subclasses.
Does your class need to re-use any high level interactions defined in another class ? The template method design pattern would be impossible to implement without inheritance. I believe all extensible frameworks use this pattern.
However, if your intention is purely that of code re-use, then composition most likely is a better design choice.
Inheritance is a very powerfull machanism for code reuse. But needs to be used properly. I would say that inheritance is used correctly if the subclass is also a subtype of the parent class. As mentioned above, the Liskov Substitution Principle is the key point here.
Subclass is not the same as subtype. You might create subclasses that are not subtypes (and this is when you should use composition). To understand what a subtype is, lets start giving an explanation of what a type is.
When we say that the number 5 is of type integer, we are stating that 5 belongs to a set of possible values (as an example, see the possible values for the Java primitive types). We are also stating that there is a valid set of methods I can perform on the value like addition and subtraction. And finally we are stating that there are a set of properties that are always satisfied, for example, if I add the values 3 and 5, I will get 8 as a result.
To give another example, think about the abstract data types, Set of integers and List of integers, the values they can hold are restricted to integers. They both support a set of methods, like add(newValue) and size(). And they both have different properties (class invariant), Sets does not allow duplicates while List does allow duplicates (of course there are other properties that they both satisfy).
Subtype is also a type, which has a relation to another type, called parent type (or supertype). The subtype must satisfy the features (values, methods and properties) of the parent type. The relation means that in any context where the supertype is expected, it can be substitutable by a subtype, without affecting the behaviour of the execution. Let’s go to see some code to exemplify what I’m saying. Suppose I write a List of integers (in some sort of pseudo language):
class List {
data = new Array();
Integer size() {
return data.length;
}
add(Integer anInteger) {
data[data.length] = anInteger;
}
}
Then, I write the Set of integers as a subclass of the List of integers:
class Set, inheriting from: List {
add(Integer anInteger) {
if (data.notContains(anInteger)) {
super.add(anInteger);
}
}
}
Our Set of integers class is a subclass of List of Integers, but is not a subtype, due to it is not satisfying all the features of the List class. The values, and the signature of the methods are satisfied but the properties are not. The behaviour of the add(Integer) method has been clearly changed, not preserving the properties of the parent type. Think from the point of view of the client of your classes. They might receive a Set of integers where a List of integers is expected. The client might want to add a value and get that value added to the List even if that value already exist in the List. But her wont get that behaviour if the value exists. A big suprise for her!
This is a classic example of an improper use of inheritance. Use composition in this case.
(a fragment from: use inheritance properly).
Even though Composition is preferred, I would like to highlight pros of Inheritance and cons of Composition.
Pros of Inheritance:
It establishes a logical "IS A" relation. If Car and Truck are two types of Vehicle ( base class), child class IS A base class.
i.e.
Car is a Vehicle
Truck is a Vehicle
With inheritance, you can define/modify/extend a capability
Base class provides no implementation and sub-class has to override complete method (abstract) => You can implement a contract
Base class provides default implementation and sub-class can change the behaviour => You can re-define contract
Sub-class adds extension to base class implementation by calling super.methodName() as first statement => You can extend a contract
Base class defines structure of the algorithm and sub-class will override a part of algorithm => You can implement Template_method without change in base class skeleton
Cons of Composition:
In inheritance, subclass can directly invoke base class method even though it's not implementing base class method because of IS A relation. If you use composition, you have to add methods in container class to expose contained class API
e.g. If Car contains Vehicle and if you have to get price of the Car, which has been defined in Vehicle, your code will be like this
class Vehicle{
protected double getPrice(){
// return price
}
}
class Car{
Vehicle vehicle;
protected double getPrice(){
return vehicle.getPrice();
}
}
A rule of thumb I have heard is inheritance should be used when its a "is-a" relationship and composition when its a "has-a". Even with that I feel that you should always lean towards composition because it eliminates a lot of complexity.
As many people told, I will first start with the check - whether there exists an "is-a" relationship. If it exists I usually check the following:
Whether the base class can be instantiated. That is, whether the base class can be non-abstract. If it can be non-abstract I usually prefer composition
E.g 1. Accountant is an Employee. But I will not use inheritance because a Employee object can be instantiated.
E.g 2. Book is a SellingItem. A SellingItem cannot be instantiated - it is abstract concept. Hence I will use inheritacne. The SellingItem is an abstract base class (or interface in C#)
What do you think about this approach?
Also, I support #anon answer in Why use inheritance at all?
The main reason for using inheritance is not as a form of composition - it is so you can get polymorphic behaviour. If you don't need polymorphism, you probably should not be using inheritance.
#MatthieuM. says in https://softwareengineering.stackexchange.com/questions/12439/code-smell-inheritance-abuse/12448#comment303759_12448
The issue with inheritance is that it can be used for two orthogonal purposes:
interface (for polymorphism)
implementation (for code reuse)
REFERENCE
Which class design is better?
Inheritance vs. Aggregation
Composition v/s Inheritance is a wide subject. There is no real answer for what is better as I think it all depends on the design of the system.
Generally type of relationship between object provide better information to choose one of them.
If relation type is "IS-A" relation then Inheritance is better approach.
otherwise relation type is "HAS-A" relation then composition will better approach.
Its totally depend on entity relationship.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
There are two schools of thought on how to best extend, enhance, and reuse code in an object-oriented system:
Inheritance: extend the functionality of a class by creating a subclass. Override superclass members in the subclasses to provide new functionality. Make methods abstract/virtual to force subclasses to "fill-in-the-blanks" when the superclass wants a particular interface but is agnostic about its implementation.
Aggregation: create new functionality by taking other classes and combining them into a new class. Attach an common interface to this new class for interoperability with other code.
What are the benefits, costs, and consequences of each? Are there other alternatives?
I see this debate come up on a regular basis, but I don't think it's been asked on
Stack Overflow yet (though there is some related discussion). There's also a surprising lack of good Google results for it.
It's not a matter of which is the best, but of when to use what.
In the 'normal' cases a simple question is enough to find out if we need inheritance or aggregation.
If The new class is more or less as the original class. Use inheritance. The new class is now a subclass of the original class.
If the new class must have the original class. Use aggregation. The new class has now the original class as a member.
However, there is a big gray area. So we need several other tricks.
If we have used inheritance (or we plan to use it) but we only use part of the interface, or we are forced to override a lot of functionality to keep the correlation logical. Then we have a big nasty smell that indicates that we had to use aggregation.
If we have used aggregation (or we plan to use it) but we find out we need to copy almost all of the functionality. Then we have a smell that points in the direction of inheritance.
To cut it short. We should use aggregation if part of the interface is not used or has to be changed to avoid an illogical situation. We only need to use inheritance, if we need almost all of the functionality without major changes. And when in doubt, use Aggregation.
An other possibility for, the case that we have an class that needs part of the functionality of the original class, is to split the original class in a root class and a sub class. And let the new class inherit from the root class. But you should take care with this, not to create an illogical separation.
Lets add an example. We have a class 'Dog' with methods: 'Eat', 'Walk', 'Bark', 'Play'.
class Dog
Eat;
Walk;
Bark;
Play;
end;
We now need a class 'Cat', that needs 'Eat', 'Walk', 'Purr', and 'Play'. So first try to extend it from a Dog.
class Cat is Dog
Purr;
end;
Looks, alright, but wait. This cat can Bark (Cat lovers will kill me for that). And a barking cat violates the principles of the universe. So we need to override the Bark method so that it does nothing.
class Cat is Dog
Purr;
Bark = null;
end;
Ok, this works, but it smells bad. So lets try an aggregation:
class Cat
has Dog;
Eat = Dog.Eat;
Walk = Dog.Walk;
Play = Dog.Play;
Purr;
end;
Ok, this is nice. This cat does not bark anymore, not even silent. But still it has an internal dog that wants out. So lets try solution number three:
class Pet
Eat;
Walk;
Play;
end;
class Dog is Pet
Bark;
end;
class Cat is Pet
Purr;
end;
This is much cleaner. No internal dogs. And cats and dogs are at the same level. We can even introduce other pets to extend the model. Unless it is a fish, or something that does not walk. In that case we again need to refactor. But that is something for an other time.
At the beginning of GOF they state
Favor object composition over class inheritance.
This is further discussed here
The difference is typically expressed as the difference between "is a" and "has a". Inheritance, the "is a" relationship, is summed up nicely in the Liskov Substitution Principle. Aggregation, the "has a" relationship, is just that - it shows that the aggregating object has one of the aggregated objects.
Further distinctions exist as well - private inheritance in C++ indicates a "is implemented in terms of" relationship, which can also be modeled by the aggregation of (non-exposed) member objects as well.
Here's my most common argument:
In any object-oriented system, there are two parts to any class:
Its interface: the "public face" of the object. This is the set of capabilities it announces to the rest of the world. In a lot of languages, the set is well defined into a "class". Usually these are the method signatures of the object, though it varies a bit by language.
Its implementation: the "behind the scenes" work that the object does to satisfy its interface and provide functionality. This is typically the code and member data of the object.
One of the fundamental principles of OOP is that the implementation is encapsulated (ie:hidden) within the class; the only thing that outsiders should see is the interface.
When a subclass inherits from a subclass, it typically inherits both the implementation and the interface. This, in turn, means that you're forced to accept both as constraints on your class.
With aggregation, you get to choose either implementation or interface, or both -- but you're not forced into either. The functionality of an object is left up to the object itself. It can defer to other objects as it likes, but it's ultimately responsible for itself. In my experience, this leads to a more flexible system: one that's easier to modify.
So, whenever I'm developing object-oriented software, I almost always prefer aggregation over inheritance.
I gave an answer to "Is a" vs "Has a" : which one is better?.
Basically I agree with other folks: use inheritance only if your derived class truly is the type you're extending, not merely because it contains the same data. Remember that inheritance means the subclass gains the methods as well as the data.
Does it make sense for your derived class to have all the methods of the superclass? Or do you just quietly promise yourself that those methods should be ignored in the derived class? Or do you find yourself overriding methods from the superclass, making them no-ops so no one calls them inadvertently? Or giving hints to your API doc generation tool to omit the method from the doc?
Those are strong clues that aggregation is the better choice in that case.
I see a lot of "is-a vs. has-a; they're conceptually different" responses on this and the related questions.
The one thing I've found in my experience is that trying to determine whether a relationship is "is-a" or "has-a" is bound to fail. Even if you can correctly make that determination for the objects now, changing requirements mean that you'll probably be wrong at some point in the future.
Another thing I've found is that it's very hard to convert from inheritance to aggregation once there's a lot of code written around an inheritance hierarchy. Just switching from a superclass to an interface means changing nearly every subclass in the system.
And, as I mentioned elsewhere in this post, aggregation tends to be less flexible than inheritance.
So, you have a perfect storm of arguments against inheritance whenever you have to choose one or the other:
Your choice will likely be the wrong one at some point
Changing that choice is difficult once you've made it.
Inheritance tends to be a worse choice as it's more constraining.
Thus, I tend to choose aggregation -- even when there appears to be a strong is-a relationship.
The question is normally phrased as Composition vs. Inheritance, and it has been asked here before.
I wanted to make this a comment on the original question, but 300 characters bites [;<).
I think we need to be careful. First, there are more flavors than the two rather specific examples made in the question.
Also, I suggest that it is valuable not to confuse the objective with the instrument. One wants to make sure that the chosen technique or methodology supports achievement of the primary objective, but I don't thing out-of-context which-technique-is-best discussion is very useful. It does help to know the pitfalls of the different approaches along with their clear sweet spots.
For example, what are you out to accomplish, what do you have available to start with, and what are the constraints?
Are you creating a component framework, even a special purpose one? Are interfaces separable from implementations in the programming system or is it accomplished by a practice using a different sort of technology? Can you separate the inheritance structure of interfaces (if any) from the inheritance structure of classes that implement them? Is it important to hide the class structure of an implementation from the code that relies on the interfaces the implementation delivers? Are there multiple implementations to be usable at the same time or is the variation more over-time as a consequence of maintenance and enhancememt? This and more needs to be considered before you fixate on a tool or a methodology.
Finally, is it that important to lock distinctions in the abstraction and how you think of it (as in is-a versus has-a) to different features of the OO technology? Perhaps so, if it keeps the conceptual structure consistent and manageable for you and others. But it is wise not to be enslaved by that and the contortions you might end up making. Maybe it is best to stand back a level and not be so rigid (but leave good narration so others can tell what's up). [I look for what makes a particular portion of a program explainable, but some times I go for elegance when there is a bigger win. Not always the best idea.]
I'm an interface purist, and I am drawn to the kinds of problems and approaches where interface purism is appropriate, whether building a Java framework or organizing some COM implementations. That doesn't make it appropriate for everything, not even close to everything, even though I swear by it. (I have a couple of projects that appear to provide serious counter-examples against interface purism, so it will be interesting to see how I manage to cope.)
I'll cover the where-these-might-apply part. Here's an example of both, in a game scenario. Suppose, there's a game which has different types of soldiers. Each soldier can have a knapsack which can hold different things.
Inheritance here?
There's a marine, green beret & a sniper. These are types of soldiers. So, there's a base class Soldier with Marine, Green Beret & Sniper as derived classes
Aggregation here?
The knapsack can contain grenades, guns (different types), knife, medikit, etc. A soldier can be equipped with any of these at any given point in time, plus he can also have a bulletproof vest which acts as armor when attacked and his injury decreases to a certain percentage. The soldier class contains an object of bulletproof vest class and the knapsack class which contains references to these items.
I think it's not an either/or debate. It's just that:
is-a (inheritance) relationships occur less often than has-a (composition) relationships.
Inheritance is harder to get right, even when it's appropriate to use it, so due diligence has to be taken because it can break encapsulation, encourage tight coupling by exposing implementation and so forth.
Both have their place, but inheritance is riskier.
Although of course it wouldn't make sense to have a class Shape 'having-a' Point and a Square classes. Here inheritance is due.
People tend to think about inheritance first when trying to design something extensible, that is what's wrong.
Favour happens when both candidate qualifies. A and B are options and you favour A. The reason is that composition offers more extension/flexiblity possiblities than generalization. This extension/flexiblity refers mostly to runtime/dynamic flexibility.
The benefit is not immediately visible. To see the benefit you need to wait for the next unexpected change request. So in most cases those sticked to generlalization fails when compared to those who embraced composition(except one obvious case mentioned later). Hence the rule. From a learning point of view if you can implement a dependency injection successfully then you should know which one to favour and when. The rule helps you in making a decision as well; if you are not sure then select composition.
Summary: Composition :The coupling is reduced by just having some smaller things you plug into something bigger, and the bigger object just calls the smaller object back. Generlization: From an API point of view defining that a method can be overridden is a stronger commitment than defining that a method can be called. (very few occassions when Generalization wins). And never forget that with composition you are using inheritance too, from a interface instead of a big class
Both approaches are used to solve different problems. You don't always need to aggregate over two or more classes when inheriting from one class.
Sometimes you do have to aggregate a single class because that class is sealed or has otherwise non-virtual members you need to intercept so you create a proxy layer that obviously isn't valid in terms of inheritance but so long as the class you are proxying has an interface you can subscribe to this can work out fairly well.
I'm currently writing a series of specialized data structure classes for a project I'm working on and I noticed that they all more or less share several completely identical properties and functions.
I could either just live with the duplicate code or let them inherit from a shared base class so that the total amount of code is reduced ALOT (which makes the whole thing much more maintainable). But alas I can't decide on what to do at this point.
I more or less understand the pros of the inheritance route but what are the cons when you compare it to having duplicate code lying around?
Which route is the more sane one to go for a 'long term' project?
From a design perspective, inheritance violates encapsulation. By inheriting from a class you link the new class with the implementation details of the parent, not all of which may be necessary for the particular implementation of the inheriting class.
For instance, let's say you have a class vehicle. This class has a number of private variables, e.g., weight_, maxSpeed_, and fuelCapacity_.
Now let's say you inherit to the class bicycle. The new class will have all the details associated with fuelCapacity_, even though they are not needed. This kind of thing can be quite a pain as the objects get more complex as changes which break the parent can also break the inheriting classes, even if they don't actually use that volatile part of the code.
A much safer choice is composition.
Is it a good concept to use multiple inheritance or can I do other things instead?
Multiple inheritance (abbreviated as MI) smells, which means that usually, it was done for bad reasons, and it will blow back in the face of the maintainer.
Summary
Consider composition of features, instead of inheritance
Be wary of the Diamond of Dread
Consider inheritance of multiple interfaces instead of objects
Sometimes, Multiple Inheritance is the right thing. If it is, then use it.
Be prepared to defend your multiple-inherited architecture in code reviews
1. Perhaps composition?
This is true for inheritance, and so, it's even more true for multiple inheritance.
Does your object really need to inherit from another? A Car does not need to inherit from an Engine to work, nor from a Wheel. A Car has an Engine and four Wheel.
If you use multiple inheritance to resolve these problems instead of composition, then you've done something wrong.
2. The Diamond of Dread
Usually, you have a class A, then B and C both inherit from A. And (don't ask me why) someone then decides that D must inherit both from B and C.
I've encountered this kind of problem twice in eight years, and it is amusing to see because of:
How much of a mistake it was from the beginning (In both cases, D should not have inherited from both B and C), because this was bad architecture (in fact, C should not have existed at all...)
How much maintainers were paying for that, because in C++, the parent class A was present twice in its grandchild class D, and thus, updating one parent field A::field meant either updating it twice (through B::field and C::field), or having something go silently wrong and crash, later (new a pointer in B::field, and delete C::field...)
Using the keyword virtual in C++ to qualify the inheritance avoids the double layout described above if this is not what you want, but anyway, in my experience, you're probably doing something wrong...
In Object hierarchy, you should try to keep the hierarchy as a Tree (a node has ONE parent), not as a graph.
More about the Diamond (edit 2017-05-03)
The real problem with the Diamond of Dread in C++ (assuming the design is sound - have your code reviewed!), is that you need to make a choice:
Is it desirable for the class A to exist twice in your layout, and what does it mean? If yes, then by all means inherit from it twice.
if it should exist only once, then inherit from it virtually.
This choice is inherent to the problem, and in C++, unlike other languages, you can actually do it without dogma forcing your design at language level.
But like all powers, with that power comes responsibility: Have your design reviewed.
3. Interfaces
Multiple inheritance of zero or one concrete classes, and zero or more interfaces is usually Okay, because you won't encounter the Diamond of Dread described above. In fact, this is how things are done in Java.
Usually, what you mean when C inherits from A and B is that users can use C as if it was an A, and/or as if it was a B.
In C++, an interface is an abstract class which has:
all its method declared pure virtual (suffixed by = 0) (removed the 2017-05-03)
no member variables
The Multiple inheritance of zero to one real object, and zero or more interfaces is not considered "smelly" (at least, not as much).
More about the C++ Abstract Interface (edit 2017-05-03)
First, the NVI pattern can be used to produce an interface, because the real criteria is to have no state (i.e. no member variables, except this). Your abstract interface's point is to publish a contract ("you can call me this way, and this way"), nothing more, nothing less. The limitation of having only abstract virtual methods should be a design choice, not an obligation.
Second, in C++, it makes sense to inherit virtually from abstract interfaces, (even with the additional cost/indirection). If you don't, and the interface inheritance appears multiple times in your hierarchy, then you'll have ambiguities.
Third, object orientation is great, but it is not The Only Truth Out ThereTM in C++. Use the right tools, and always remember you have other paradigms in C++ offering different kinds of solutions.
4. Do you really need Multiple Inheritance?
Sometimes, yes.
Usually, your C class is inheriting from A and B, and A and B are two unrelated objects (i.e. not in the same hierarchy, nothing in common, different concepts, etc.).
For example, you could have a system of Nodes with X,Y,Z coordinates, able to do a lot of geometric calculations (perhaps a point, part of geometric objects) and each Node is an Automated Agent, able to communicate with other agents.
Perhaps you already have access to two libraries, each with its own namespace (another reason to use namespaces... But you use namespaces, don't you?), one being geo and the other being ai
So you have your own own::Node derive both from ai::Agent and geo::Point.
This is the moment when you should ask yourself if you should not use composition instead. If own::Node is really really both a ai::Agent and a geo::Point, then composition will not do.
Then you'll need multiple inheritance, having your own::Node communicate with other agents according to their position in a 3D space.
(You'll note that ai::Agent and geo::Point are completely, totally, fully UNRELATED... This drastically reduces the danger of multiple inheritance)
Other cases (edit 2017-05-03)
There are other cases:
using (hopefully private) inheritance as implementation detail
some C++ idioms like policies could use multiple inheritance (when each part needs to communicate with the others through this)
the virtual inheritance from std::exception (Is Virtual Inheritance necessary for Exceptions?)
etc.
Sometimes you can use composition, and sometimes MI is better. The point is: You have a choice. Do it responsibly (and have your code reviewed).
5. So, should I do Multiple Inheritance?
Most of the time, in my experience, no. MI is not the right tool, even if it seems to work, because it can be used by the lazy to pile features together without realizing the consequences (like making a Car both an Engine and a Wheel).
But sometimes, yes. And at that time, nothing will work better than MI.
But because MI is smelly, be prepared to defend your architecture in code reviews (and defending it is a good thing, because if you're not able to defend it, then you should not do it).
From an interview with Bjarne Stroustrup:
People quite correctly say that you don't need multiple inheritance, because anything you can do with multiple inheritance you can also do with single inheritance. You just use the delegation trick I mentioned. Furthermore, you don't need any inheritance at all, because anything you do with single inheritance you can also do without inheritance by forwarding through a class. Actually, you don't need any classes either, because you can do it all with pointers and data structures. But why would you want to do that? When is it convenient to use the language facilities? When would you prefer a workaround? I've seen cases where multiple inheritance is useful, and I've even seen cases where quite complicated multiple inheritance is useful. Generally, I prefer to use the facilities offered by the language to doing workarounds
There's no reason to avoid it and it can be very useful in situations. You need to be aware of the potential issues though.
The biggest one being the diamond of death:
class GrandParent;
class Parent1 : public GrandParent;
class Parent2 : public GrandParent;
class Child : public Parent1, public Parent2;
You now have two "copies" of GrandParent within Child.
C++ has thought of this though and lets you do virtual inheritence to get around the issues.
class GrandParent;
class Parent1 : public virtual GrandParent;
class Parent2 : public virtual GrandParent;
class Child : public Parent1, public Parent2;
Always review your design, ensure you are not using inheritance to save on data reuse. If you can represent the same thing with composition (and typically you can) this is a far better approach.
See w:Multiple Inheritance.
Multiple inheritance has received
criticism and as such, is not
implemented in many languages.
Criticisms includes:
Increased complexity
Semantic ambiguity often summarized as the diamond
problem.
Not being able to explicitly inherit multiple times from a single
class
Order of inheritance changing class semantics.
Multiple inheritance in languages with
C++/Java style constructors
exacerbates the inheritance problem of
constructors and constructor chaining,
thereby creating maintenance and
extensibility problems in these
languages. Objects in inheritance
relationships with greatly varying
construction methods are hard to
implement under the constructor
chaining paradigm.
Modern way of resolving this to use interface (pure abstract class) like COM and Java interface.
I can do other things in place of this?
Yes, you can. I am going to steal from GoF.
Program to an Interface, not an Implementation
Prefer composition over inheritance
Public inheritance is an IS-A relationship, and sometimes a class will be an type of several different classes, and sometimes it's important to reflect this.
"Mixins" are also sometimes useful. They are generally small classes, usually not inheriting from anything, providing useful functionality.
As long as the inheritance hierarchy is fairly shallow (as it should almost always be), and well managed, you're unlikely to get the dreaded diamond inheritance. The diamond isn't a problem with all languages that use multiple inheritance, but C++'s treatment of it is frequently awkward and sometimes puzzling.
While I've run into cases where multiple inheritance is very handy, they're actually fairly rare. This is likely because I prefer to use other design methods when I don't really need multiple inheritance. I do prefer to avoid confusing language constructs, and it's easy to construct inheritance cases where you have to read the manual really well to figure out what's going on.
You shouldn't "avoid" multiple inheritance but you should be aware of problems that can arise such as the 'diamond problem' ( http://en.wikipedia.org/wiki/Diamond_problem ) and treat the power given to you with care, as you should with all powers.
At the risk of getting a bit abstract, I find it illuminating to think about inheritance within the frame of category theory.
If we think of all our classes and arrows between them denoting inheritance relations, then something like this
A --> B
means that class B derives from class A. Note that, given
A --> B, B --> C
we say C derives from B which derives from A, so C is also said to derive from A, thus
A --> C
Furthermore, we say that for every class A that trivially A derives from A, thus our inheritance model fulfills the definition of a category. In more traditional language, we have a category Class with objects all classes and morphisms the inheritance relations.
That's a bit of setup, but with that let's take a look at our Diamond of Doom:
C --> D
^ ^
| |
A --> B
It's a shady looking diagram, but it'll do. So D inherits from all of A, B, and C. Furthermore, and getting closer to addressing OP's question, D also inherits from any superclass of A. We can draw a diagram
C --> D --> R
^ ^
| |
A --> B
^
|
Q
Now, problems associated with the Diamond of Death here are when C and B share some property/method names and things get ambiguous; however, if we move any shared behavior into A then the ambiguity disappears.
Put in categorical terms, we want A, B and C to be such that if B and C inherit from Q then A can be rewritten as as subclass of Q. This makes A something called a pushout.
There is also a symmetric construction on D called a pullback. This is essentially the most general useful class you can construct which inherits from both B and C. That is, if you have any other class R multiply inheriting from B and C, then D is a class where R can be rewritten as as subclass of D.
Making sure your tips of the diamond are pullbacks and pushouts gives us a nice way to generically handle name-clashing or maintenance issues which might arise otherwise.
Note Paercebal's answer inspired this as his admonitions are implied by the above model given that we work in the full category Class of all possible classes.
I wanted to generalize his argument to something which shows how complicated multiple inheritance relationships can be both powerful and non-problematic.
TL;DR Think of the inheritance relationships in your program as forming a category. Then you can avoid Diamond of Doom problems by making multiply-inherited classes pushouts and symmetrically, making a common parent class which is a pullback.
We use Eiffel. We have excellent MI. No worries. No issues. Easily managed. There are times to NOT use MI. However, it useful more than people realize because they are: A) in a dangerous language that does not manage it well -OR- B) satisfied with how they've worked around MI for years and years -OR- C) other reasons (too numerous to list I am quite sure--see answers above).
For us, using Eiffel, MI is as natural as anything else and another fine tool in the toolbox. Frankly, we're quite unconcerned that no one else is using Eiffel. No worries. We are happy with what we have and invite you to have a look.
While you're looking: Take special note of Void-safety and the eradication of Null pointer dereferencing. While we're all dancing around MI, your pointers are getting lost! :-)
You should use it carefully, there are some cases, like the Diamond Problem, when things can go complicated.
(source: learncpp.com)
Every programming language has a slightly different treatment of object-oriented programming with pros and cons. C++'s version places the emphasis squarely on performance and has the accompanying downside that it is disturbingly easy to write invalid code - and this is true of multiple inheritance. As a consequence there is a tendency to steer programmers away from this feature.
Other people have addressed the question of what multiple inheritance isn't good for. But we have seen quite a few comments that more-or-less imply that the reason to avoid it is because it's not safe. Well, yes and no.
As is often true in C++, if you follow a basic guideline you can use it safely without having to "look over your shoulder" constantly. The key idea is that you distinguish a special kind of class definition called a "mix-in"; class is a mix-in if all its member functions are virtual (or pure virtual). Then you are allowed to inherit from a single main class and as many "mix-ins" as you like - but you should inherit mixins with the keyword "virtual". e.g.
class CounterMixin {
int count;
public:
CounterMixin() : count( 0 ) {}
virtual ~CounterMixin() {}
virtual void increment() { count += 1; }
virtual int getCount() { return count; }
};
class Foo : public Bar, virtual public CounterMixin { ..... };
My suggestion is that if you intend to use a class as a mix-in class you also adopt a naming convention to make it easy for anyone reading the code to see what's happening & to verify you're playing by the rules of the basic guideline. And you'll find it works much better if your mix-ins have default constructors too, just because of the way virtual base classes work. And remember to make all the destructors virtual too.
Note that my use of the word "mix-in" here isn't the same as the parameterised template class (see this link for a good explanation) but I think it is a fair use of the terminology.
Now I don't want to give the impression that this is the only way to use multiple inheritance safely. It's just one way that is fairly easy to check.
Uses and Abuses of Inheritance.
The article does a great job of explaining inheritance, and it's dangers.
Beyond the diamond pattern, multiple inheritance tends to make the object model harder to understand, which in turn increases maintenance costs.
Composition is intrinsically easy to understand, comprehend, and explain. It can get tedious to write code for, but a good IDE (it's been a few years since I've worked with Visual Studio, but certainly the Java IDEs all have great composition shortcut automating tools) should get you over that hurdle.
Also, in terms of maintenance, the "diamond problem" comes up in non-literal inheritance instances as well. For instance, if you have A and B and your class C extends them both, and A has a 'makeJuice' method which makes orange juice and you extend that to make orange juice with a twist of lime: what happens when the designer for 'B' adds a 'makeJuice' method which generates and electrical current? 'A' and 'B' may be compatible "parents" right now, but that doesn't mean they will always be so!
Overall, the maxim of tending to avoid inheritance, and especially multiple inheritance, is sound. As all maxims, there are exceptions, but you need to make sure that there is a flashing green neon sign pointing at any exceptions you code (and train your brain so that any time you see such inheritance trees you draw in your own flashing green neon sign), and that you check to make sure it all makes sense every once in a while.
The key issue with MI of concrete objects is that rarely do you have an object that legitimately should "Be an A AND be a B", so it is rarely the correct solution on logical grounds. Far more often, you have an object C that obeys "C can act as an A or a B", which you can achieve via interface inheritance & composition. But make no mistake- inheritance of multiple interfaces is still MI, just a subset of it.
For C++ in particular, the key weakness of the feature isn't the actual EXISTENCE of Multiple Inheritance, but some constructs it allows that are almost always malformed. For example, inheriting multiple copies of the same object like:
class B : public A, public A {};
is malformed BY DEFINITION. Translated into English this is "B is an A and an A". So, even in human language there's a severe ambiguity. Did you mean "B has 2 As" or just "B is an A"?. Allowing such pathological code, and worse making it a usage example, did C++ no favors when it came to making a case for keeping the feature in successor languages.
You can use composition in preference to inheritance.
The general feeling is that composition is better, and it's very well discussed.
it takes 4/8 bytes per class involved.
(One this pointer per class).
This might never be a concern, but if one day you have a micro data structure which is instanced billions of time it will be.