Skip to content
Ben Sharpe edited this page Jan 31, 2014 · 3 revisions

Mixins can be used for sharing methods between classes, without requiring them to inherit from the same father.

  local class = require 'middleclass'
  HasWings = { -- HasWings is a module, not a class. It can be "included" into classes
    fly = function(self)
      print('flap flap flap I am a ' .. self.class.name)
    end
  }

  Animal = class('Animal')

  Insect = class('Insect', Animal) -- or Animal:subclass('Insect')

  Worm = class('Worm', Insect) -- worms don't have wings

  Bee = class('Bee', Insect)
  Bee:include(HasWings) --Bees have wings. This adds fly() to Bee

  Mammal = class('Mammal', Animal)

  Fox = class('Fox', Mammal) -- foxes don't have wings, but are mammals

  Bat = class('Bat', Mammal)
  Bat:include(HasWings) --Bats have wings, too.

  local bee = Bee() -- or Bee:new()
  local bat = Bat() -- or Bat:new()
  bee:fly()
  bat:fly()

Output:

flap flap flap I am a Bee
flap flap flap I am a Bat

Included

Mixins can provide a special function called 'included'. This function will be invoked when the mixin is included on a class, allowing the programmer to do actions. The only two parameters are the mixin (normally implicit) and the class.

  local class = require 'middleclass'
  DrinksCoffee = {}

  -- This is another valid way of declaring functions on a mixin.
  -- Note that we are using the : operator, so there's an implicit self parameter
  function DrinksCoffee:drink(drinkTime)
    if(drinkTime~=self.class.coffeeTime) then
      print(self.name .. ': It is not the time to drink coffee!')
    else
      print(self.name .. ': Mmm I love coffee at ' .. drinkTime)
    end
  end

  -- the included method is invoked every time DrinksCoffee is included on a class
  -- notice that paramters can be passed around
  function DrinksCoffee:included(klass)
    print(klass.name .. ' drinks coffee at ' .. klass.coffeeTime)
  end

  EnglishMan = class('EnglishMan')
  EnglishMan.static.coffeeTime = 5
  EnglishMan:include(DrinksCoffee)
  function EnglishMan:initialize(name) self.name = name end

  Spaniard = class('Spaniard')
  Spaniard.static.coffeeTime = 6
  Spaniard:include(DrinksCoffee)
  function Spaniard:initialize(name) self.name = name end

  tom = EnglishMan:new('tom')
  juan = Spaniard:new('juan')

  tom:drink(5)
  juan:drink(5)
  juan:drink(6)

Output:

EnglishMan drinks coffee at 5
Spaniard drinks coffee at 6
tom: Mmm I love coffee at 5
juan: It is not the time to drink coffee!
juan: Mmm I love coffee at 6
Clone this wiki locally