-
Notifications
You must be signed in to change notification settings - Fork 192
Mixins
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
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