1. 程式人生 > 其它 >【Lua】面向物件的實現方式

【Lua】面向物件的實現方式

技術標籤:Cocos遊戲開發引擎計算機語言程式設計lua

第一種實現方式:(實現了私有變數和公有變數)

local BaseClass = {
    ctor = function (self, params)
        self._name = params.name or "John"
        self._sex = params.sex or "man"
    end,

    new = function (mt, params)
        local instance = {
            privateElements = {},
            publicElements = {},
            classIndex = 0
        }
        setmetatable(instance, {
            __index = function (tb, key)
                if tb.classIndex == 0 then
                    if type(key) == "string" and string.sub(key,1,1) == "_" then
                        assert(false, "Private variables cannot be accessed.")
                    end
                    if tb.publicElements[key] then
                        if type(tb.publicElements[key]) == "function" then
                            return function (obj, ...)
                                local oriIndex = tb.classIndex
                                tb.classIndex = 1
                                local ret = {tb.publicElements[key](obj, ...)}
                                tb.classIndex = oriIndex
                                return unpack(ret)
                            end
                        else
                            return tb.publicElements[key]
                        end
                    end
                else
                    return tb.publicElements[key] or tb.privateElements[key]
                end
            end,
            __newindex = function (tb, key, value)
                if tb.classIndex == 0 then
                    if type(key) == "string" and string.sub(key,1,1) == "_" then
                        assert(false, "Private variables cannot be accessed.")
                    end
                    tb.publicElements[key] = value
                else
                    if type(key) == "string" and string.sub(key,1,1) == "_" then
                        tb.privateElements[key] = value
                    else
                        tb.publicElements[key] = value
                    end
                end
            end
        })
        for key, value in pairs(mt) do
            if type(key) == "string" and string.sub(key,1,1) == "_" then
                instance.privateElements[key] = value
            else
                instance.publicElements[key] = value
            end
        end
        instance:ctor(params)
        return instance
    end,

    getName = function (self)
        return self._name
    end,

    getSex = function (self)
        return self._sex
    end
}

local john = BaseClass:new({name = "John", sex = "man"})
local marry = BaseClass:new({name = "marry", sex = "marry"})

print(john:getName())
print(john:getSex())

print(marry:getName())
print(marry:getSex())

測試結果:

第二種實現方式 :

local BaseClass = {
    ctor = function (self, params)
        self._name = params.name or "John"
        self._sex = params.sex or "man"
    end,

    new = function (mt, params)
        local instance = { }
        setmetatable(instance, mt)
        mt.__index = mt
        instance:ctor(params)
        return instance
    end,

    getName = function (self)
        return self._name
    end,

    getSex = function (self)
        return self._sex
    end
}

local john = BaseClass:new({name = "John", sex = "man"})
local marry = BaseClass:new({name = "marry", sex = "women"})

print(john:getName())
print(john:getSex())

print(marry:getName())
print(marry:getSex())

測試結果: