38. Lua 多重繼承

需求:
創(chuàng)建一個對象 , 使其繼承父類 : Named , Account , 成功調(diào)用父類方法

  -- 在 table 'plist' 查找k
  local function search( k , plist )
    for i = 1 , #plist do
        local v = plist[i][k]  -- 嘗試第i個基類
        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
    })

    -- 將 'c'作為其實例的元表
    c.__index = c

    -- 為新類定義構(gòu)造函數(shù)(construction)
    function c:new(o)
        o = o or {}
        setmetatable( o , c )
        return o
    end
    return c  -- 返回新建的類
  end

  -- 父類1 開始
  Named = {}
  function Named:getName()
    return self.name
  end
  -- 父類1 結(jié)束

  function Named:setName(n)
    self.name = n
  end

  -- 父類2 開始
  Account = { balance = 0 }

  function Account:new(o)
    o = o or {}
    setmetatable( o , self )
    self.__index = self
    return o
  end

  -- 存款方法
  function Account:deposit(v)
    self.balance = self.balance + v
  end

  -- 取款方法
  function Account:withdraw(v)
    if v > self.balance then
        error "insufficient funds"
    end
    self.balance = self.balance - v
  end
  -- 父類2 結(jié)束

  NamedAccount = createClass( Account , Named ) -- 創(chuàng)建新的 NamedAccount 類
  account = NamedAccount:new( { name="Paul" } )
  print("account:getName() : " .. account:getName())
  print("account.balance : " .. account.balance)

注意 : 改進(jìn) 上面方法完成了多繼承 但效率不高,可如下修改,將父類的變量直接復(fù)制過來 , 但這樣缺點是, 運行后,不可進(jìn)行修改,因為并沒有真的繼承父類,只是簡單把父類的變量賦值過來而已

-- 修改上面代碼中的 setmetatable 方法
setmetatable( c , { __index = function(t, k )
  local v = search( k , parents )
  t[k] = v -- 保存下來, 以備下次訪問
  return v
end
})

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容