5

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

  • allows for mixins with a non-verbose syntax
  • allows us to treat 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)
//
8
  • Would you consider this a duplicate of Why use inheritance at all? ? Commented Sep 16, 2011 at 23:42
  • 1
    @daxelrod no because that's comparing inheritance to delegation and it also doesn't answer my question. My question is mainly about building class relations as trees versus flat lists. Commented Sep 16, 2011 at 23:49
  • What are FullTime and PartTime when they're not associated with Employee? Commented Sep 17, 2011 at 0:15
  • @TerryWilcox I believe loose coupling of FullTime from Employee is a habit of over engineering on my part Commented Sep 17, 2011 at 0:26
  • Then I think you've answered your own question. Prefer composition over inheritance, but use inheritance when it makes sense. FullTimeEmployee makes more sense as a subclass of Employee than it does as an Employee with a FullTime. Commented Sep 17, 2011 at 0:41

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

5 Comments

The main difference is chaining. Why would you set up an inheritance chain/tree when you can just have a flat list or linked list.
Also how are mixins different from classical inheritance in popular implementations? Am I confusing how mixins work?
I already know the value of inheritance & composition in JS but that's prototypical inheritance instead of classical inheritance. Which is a different ball game. Also in SC extend is not inheritance. It's just another name for mixin.
right, but extend adds the stuff in the argument to the prototype, so its creating a 'class'. class in quotes, because of the prototypical inheritance. That's my point, there is little difference between 'mixing something in' and 'extending'
links to source. Again the main difference is that extension is a live link, where as mixed in objects are static shallow clones.
0

You should use when the necessity appears. If you have a big class with 1000 lines and you are finding yourself repeating the same stuff across multiple classes you can encapsulate some logic in a base class and other in mixins. Each mixin has a limited context, they might be aware about more than they should, but they only focus on a certain task. Therefore are very modular. Well, the best example I can give it to you is an Actor for a game which has inheritance for some base stuff but uses mixins/plugins for shared functionality. The shared functionality could be (directly from the source code!):

var plugins = {
    SingleVisualEntity : SingleVisualEntity,
    JumpBehaviour      : JumpBehaviour,
    WeaponBehaviour    : WeaponBehaviour,
    RadarBehaviour     : RadarBehaviour,
    EnergyGatherer     : EnergyGatherer,
    LifeBarPlugin      : LifeBarPlugin,
    SelectionPlugin    : SelectionPlugin,
    UpgradePlugin      : UpgradePlugin,
    BrainPlugin        : BrainPlugin,
    PlanetObjectPlugin : PlanetObjectPlugin,
}

This originally was a class with +1000 lines.

Comments

-1

When designing we try to simulate reality as much as we can.

Considering the is a and the has a principles, a FullTimeEmployee is an Employee who has additional (extra) feature, and not some new thing that has an Employee beside something called FullTime, and so on for the PartTimeEmployee.

2 Comments

mixins are not has an. If FullTimeEmployee had a field named Employee then that's a has an relation.
@Raynos: If FullTimeEmployee had a field named Employee then logically he would no longer be an Employee, but something that has a or includes an Employee. another Example is that a Taxi is a car that has some specifiactions, we can't say that a Taxi has a car, that is not reasonable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.