gist
What are the reasons to favour inheritance over mixins
Given the following psuedo-code example :
class Employee
class FullTimeEmployee inherits Employee
class PartTimeEmployee inherits Employee
// versus
class Employee
class WorksPartTime
class WorksFullTime
class FullTimeEmployee includes Employee, WorksFullTime
class PartTimeEmployee includes Employee, WorksPartTime
If we were to use inheritance to build objects the class relations would be seen as a tree where as with mixins the class relations would be seen as a flat list.
Assuming the language we are using
FullTimeEmployee
as both a Employee
and FullTime
object transparently.why should we build up our class relations as trees (inheritance) instead of flat lists (composition)?
Example of tree versus list.
class Person
class Employee inherits Person
class FullTimeEmployee inherits Employee
// -> FullTimeEmployee
// Person -> Employee
// -> PartTimeEmployee
class Person
class Employee includes Person
class FullTime
class FullTimeEmployee includes FullTime, Employee
//
// FullTimeEmployee = (FullTime, Employee, Person)
//
I would argue that in languages that do support mixins, it is effectively the same as using (multiple) inheritance. In both cases, the same methods/properties exist on the class/object in question, both are invoked the exact same way -- there is no practical distinction. I'm also assuming that in this hypothetical language, you can 'extend' from multiple 'classes' as well.
If this is all true, then in a way they are equivalent and the question doesn't make sense - neither is better than the other because they are functionality equivalent.
In a human-understanding sort of way, I think most people think of inheritance in terms of the isA
relationship, and mixins in terms of decorating something with functionality.
If you can only inherit from one 'class', then obviously mixins are a way to sort of gain multiple inheritance.
EDIT -- based on your comments, which are good, I would say the details of the hypothetical language matter. I will admit I am basing my answer of the Sproutcore, which is a Javascript framework that has formalized support for both mixins and inheritance. In SC, you can do
App.MyObject = SC.Object.extend({
prop: 'prop',
func: function(){
})
which does what you would expect, it puts prop
and func
on the prototype of MyObject
, creating a "class", which could have subclasses. You could also do
App.MyObject = SC.Object.extend(App.OtherObject, {
// stuff
})
which does multiple inheritance. You could then have something like
CommonFunctionality = {
// some methods
};
App.mixin(CommonFunctionality);
which would apply the CommonFunctionality
stuff to App
. If app was a namespace (i.e. a {}
) the methods of CommonFunctionality
would be applied to that object literal. If it made sense, you could also apply CommonFunctionality
to a "class", and its methods would be on the prototype. If you look in the source, you see
SC.extend = SC.mixin ;
So in SC, there is absolutely no difference because they are the same method.
So details matter -- they didn't have to do it that way, but they did, and there are implications. If they had done it differently, then of course there would be different consequences.
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