以Doller和Franc兑换Rmb的策略模式类为例。
1 Object基类
模拟:创建new、继承subClass
_G
:全局tablesetmetatable(A,B)
:相当于C++重载操作符,__index作用:当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable中的__index 键。
-- object.lua
local Object = {}
-- unuse
Object.id = 1
function Object:new()
local ret = {}
self.__index = self
setmetatable(ret, self)
return ret
end
function Object:subClass(subClassName)
_G[subClassName] = {}
local obj = _G[subClassName]
self.__index = self
obj.base = self
setmetatable(obj, self)
end
return Object
2 Money类
此处需要注意:模拟调用父类方法时要手动传入调用类,否则用:
会每个对象共用在_G
中的父类的属性。
比如下面的Doller
和Franc
类中的调用self.base:exchange()
索引的是_G['Money']
里的coins
因为self.base:exchange()
传入的第一个参数是self.base
而不是self
无论怎么设置子对象coins
,调用exchange()
都会显示coins = 0
因为_G['Money'].coins = 0
-- Money.lua
-- [[Money基类]]
local Object = require('Object')
-- 持有N个国家的币,计算兑换成RMB数值
Object:subClass('Money')
Money.coins = 0
-- 兑换Rmb
function Money:exchange()
print('coins = ' .. self.coins)
end
-- 测试成员变量
function Money:addMoney()
print('addMoney 1')
self.coins = self.coins + 1
end
-- [[Doller类]]
Money:subClass('Doller')
function Doller:exchange()
self.base.exchange(self)
return self.coins * 7
end
-- [[Franc类]]
Money:subClass('Franc')
function Franc:exchange()
self.base.exchange(self)
return self.coins * 8
end
return { Doller, Franc }
3 运行
-- main.lua
local MoneyModule = require('Money')
local Doller, Franc = MoneyModule[1], MoneyModule[2]
print(Doller, Franc) -- table: 00F02378 table: 00F02468
local doller = Doller:new()
doller.coins = 100
doller:addMoney() -- addMoney 1
print(doller:exchange()) -- coins = 101
-- 707
local franc = Franc:new()
franc.coins = 100
franc:addMoney() -- addMoney 1
franc:addMoney() -- addMoney 1
print(franc:exchange()) -- coins = 102
-- 816