(Lua中的類 - 4)封裝一個生成類的函數(shù)

--[[
創(chuàng)建一個類的方法
原理:
    一個類,本質(zhì)上也是一個table,只是他包含了__index鍵,而且__index鍵指向它本身。
    創(chuàng)建一個類的對象,即新建一個table,并且將類(一個table)設(shè)置為其metatable。
參數(shù):
    name->類名(string類型值,必需)
    super->父類列表(table類型值或nil,非必需)
]]
function class(name, super)
    -- name必須是一個string
    if not name or type(name) ~= "string" then
        error("Name of class should be a string value.")
    end
    -- super如果有,必須是一個table,使用多繼承的形式
    if not super then
        super = {}
    else
        if type(super) ~= "table" then
            error("Super of class should be a table value.")
        end
    end

    -- 生成一個多繼承的類
    local myClass = {}
    myClass._className = name   -- 保存ClassName
    myClass._super = super      -- 保存父類列表

    myClass.__index = myClass
    setmetatable(myClass, {__index = function(tab, key) -- 元表的__index是從super列表中查找key
        for k,v in pairs(myClass._super) do
            if v[key] then
                return v[key]
            end
        end
    end})

    -- new函數(shù)
    function myClass:new()
        local obj = {}
        setmetatable(obj, myClass)
        return obj
    end

    -- release函數(shù),只是想寫個release,感覺沒什么意義
    function myClass:release()
        myClass = nil
    end

    -- 獲取類型,只是因為保存了className,所以加了個函數(shù),并沒有覺得有什么意義
    function myClass:getClass()
        return myClass._className
    end

    -- 獲取父類列表,同上只是因為保存了super列表
    function myClass:getSuper()
        return myClass._super
    end

    return myClass
end


-- 下面是測試代碼

-- 新建一個普通的類,不需要再手動寫new方法了
Person = class("Person")    -- 沒有父類

function Person:say()
    print("Person say")
end

-- 繼承一個類
Worker = class("Worker", {Person})  -- 父類是Person

function Worker:work()
    print("Worker work")
end

-- 多繼承呢
Coder = class("Coder", {Person, Worker})    -- 父類是Person和Worker

function Coder:coding()
    print("Coder coding")
end

-- 創(chuàng)建一個Coder類的對象
local me = Coder:new()
me:say()    -- Person的say,雖然Worker也有say,但是父類列表中Person在前,在__index中是先找Person類
me:work()   -- Worker的work
me:coding() -- Coder的coding

print(me:getClass())
print(#me:getSuper())

me:release()

最后編輯于
?著作權(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)容