Lua多重继承
Account = {balance = 0} function Account:withdraw(v) if v > self.balance then error"insufficient funds" end self.balance = self.balance - v end function Account:deposit(v) self.balance = self.balance + v end function Account:new(o) o = o or {} setmetatable(o, self) self.__index = self return o end Named = {} function Named:getname() return self.name end function Named:setname(n) self.name = n end local function search(k, plist) for i = 1,#plist do local v = plist[i][k] if v then return v end end end function createClass(...) local c = {} local parents = {...} setmetatable(c, {__index = function(t, k) return search(k, parents) end}) function c:new(o) o = o or {} setmetatable(o, c) c.__index = c return o end return c end NamedAccount = createClass(Account , Named) account = NamedAccount:new{name = "Paul"} print(account:getname())
执行结果为:Paul
1、首先执行createClass。该函数是返回一个table,这个table相当于一个新的类。这个table的__index字段是一个函数,函数执行的是search(k,parents)(其中k是找不到的字段名,parents作为closure的非局部变量,跟函数一起保存着)。然后为新的table定义一个new函数,这个new跟大多数的new函数一样,设定__index为自己本身
此时,NameAccount的内容为:NameAccount = {"new" = ***}。只有一个new的字段,隐式的还有__index字段,其为一个函数
2、执行完account = NamedAccount:new{name = "Paul"}之后,account的内容大致如下
account = {"name" = "Paul", "__index" = NameAccount}
3、account:getname().
(1)找不到getname字段,于是到__index下找
(2)在NameAccount中也没有getname字段,于是再在NameAccount的__index字段找
(3)NameAccount的__index字段为一个函数,其调用了search,于是执行了return search("getname", {Account, Named})。
(4)首先,i = 1,plist[1]相当于Account这个table,plist[1][k]即Account["getname"],此时为nil
然后,同样的道理,plist[2][k]为Named["getname"]。
(5)Named的getname字段就是return self.name,也就是return account.name,也就是说print("Paul")