For certain situations, composition is advocated over inheritance. I see this happening more and more in the Ruby and Javascript community.
Composition sounds a lot like multiple inheritance. I have even read that internally in some Ruby implementations, module composition IS multiple inheritance with minor syntactic sugar.
Is it the same thing? If not, how is it different than multiple inheritance?
It depends what you mean by "multiple inheritance" and "composition." If composition and inheritance both just mean adding to a list of messages that an object responds to, then they are equal by definition.
Let's say that classes are simply virtual tables of methods, and that each object in a language is defined by a reference to a class and some data. If an object responds to a message by calling a method lookup function associated with it's class, and the method lookup function either returns the method (if the class contains a method corresponding to the message) or recursively calls the method lookup function on it's superclass, we have a language with single inheritance and no composition. Multiple inheritance can be added such a language by modifying the method lookup function as described in section 2.2 of Open Extensible Object Models, by Ian Piumarta. Basically, just by adding a class which defers method lookups to multiple other classes instead of just one. It is easy to see that mixins/traits (I'm assuming this is what you mean by composition) can be added in exactly the same way.
However, if by "composition" you mean that an object has other objects as instance variables, then there is a good reason to use that instead of multiple inheritance: encapsulation. Some methods on the objects in the instance variables wouldn't make sense if they could be called on the parent object.
Lots of people talk about multiple inheritance in a technical way, but I would like to talk about the design aspect.
In a good OOP (object oriented programming) design you shouldn't use multiple inheritance. Why?
1.
Like the GRASP patterns suggest it with the high cohesion pattern, a class shouldn't have many responsabilities.
2.
Inheritance lock your architecture. If you want to change anything, you have to change everything. I give you an example: imagine some classes like car
, truck
, boat
and plane
inheriting from the class motorVehicle
. Now, I add a new concept: car, truck, boat and plane are also moving vehicle. What should I do?
motorVehicle
than a movingVehicle
?motorVehicle
and movingVehicle
. My class will have two different highly correlated responsabilities, that's really bad.And what if I add a bicycle! That's why inheritance should only be used to factorize code for classes having the same responsability!
Conclusion
If a class should only have one clearly identified responsability and you should only use inheritance for classes having the same responsability, you should never use multiple inheritance in a correct OOP design.
I would suggest you to always use composition with interfaces to have low coupling between your classes. This will give you a more scalable, maintenable and testable code!
In the previous example, using composition will lead to have some motor classes inheriting from a motor interface, some move classes inheriting from a move interface and the classes
car
,truck
, ... will "use" a motor interface and a move interface. And ourbicycle
will be able to only "use" a move interface!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With