首页 > 代码库 > Lua-面向对象中类的构造

Lua-面向对象中类的构造

在Lua中,我们可以通过table+function来模拟实现类。

 

而要模拟出类,元表(metatable)和__index元方法是必不可少的。

为一个表设置元表的方法:

table = {}

metatable = {}

setmetatable(table, metatable) 

或者

table = setmetatable({},{})

 

下面看一个简单的例子:

local t = {    k1 = "aaa"}local mt = {    k2 = "bbb",    __index = {        k3 = "ccc"    }}setmetatable(t, mt)print("k1:", t.k1, "k2:", t.k2, "k3:", t.k3)

输出:

k1:    aaa    k2:    nil    k3:    ccc

 

从例子可以看出,查找表元素时会从表的元表的__index键中查找。

查找一个表元素的规则如下:

1.在表中查找,如果找到,返回该元素;如果找不到,继续2
2.判断该表是否有元表,如果没有,返回nil;如果有,继续3
3.判断元表中是否有__index方法,
如果__index方法为nil,返回nil;
如果__index方法是一个表,则重复 1,2,3;
如果__index方法是一个函数,则返回该函数的返回值。 

 

除了有__index元方法外,还有__newindex,__add,__sub等很多原方法,可查看Lua文档

2.4 – Metatables and Metamethods

 

在了解了元表和元方法后,我们就可以模拟类的实现了。

local A = {    a1 = "this is a1",    a2 = 100}function A.new()    local o = {}    setmetatable(o, A)    A.__index = A    return oendfunction A:Print()    print("This is A:Print ")endlocal a = A.new()a:Print()

输出结果:

This is A:Print 

 

以上就是一个类的简单实现方式,当然,我们也可以把它的实现封装到一个function中,这样会更方便我们类的创建和使用。

 

下面是cocos2d引擎中,lua类的实现,以供参考:

 

技术分享
local setmetatableindex_setmetatableindex_ = function(t, index)    if type(t) == "userdata" then        local peer = tolua.getpeer(t)        if not peer then            peer = {}            tolua.setpeer(t, peer)        end        setmetatableindex_(peer, index)    else        local mt = getmetatable(t)        if not mt then mt = {} end        if not mt.__index then            mt.__index = index            setmetatable(t, mt)        elseif mt.__index ~= index then            setmetatableindex_(mt, index)        end    endendsetmetatableindex = setmetatableindex_function class(classname, ...)    local cls = {__cname = classname}    local supers = {...}    for _, super in ipairs(supers) do        local superType = type(super)        assert(superType == "nil" or superType == "table" or superType == "function",            string.format("class() - create class \"%s\" with invalid super class type \"%s\"",                classname, superType))        if superType == "function" then            assert(cls.__create == nil,                string.format("class() - create class \"%s\" with more than one creating function",                    classname));            -- if super is function, set it to __create            cls.__create = super        elseif superType == "table" then            if super[".isclass"] then                -- super is native class                assert(cls.__create == nil,                    string.format("class() - create class \"%s\" with more than one creating function or native class",                        classname));                cls.__create = function() return super:create() end            else                -- super is pure lua class                cls.__supers = cls.__supers or {}                cls.__supers[#cls.__supers + 1] = super                if not cls.super then                    -- set first super pure lua class as class.super                    cls.super = super                end            end        else            error(string.format("class() - create class \"%s\" with invalid super type",                        classname), 0)        end    end    cls.__index = cls    if not cls.__supers or #cls.__supers == 1 then        setmetatable(cls, {__index = cls.super})    else        setmetatable(cls, {__index = function(_, key)            local supers = cls.__supers            for i = 1, #supers do                local super = supers[i]                if super[key] then return super[key] end            end        end})    end    if not cls.ctor then        -- add default constructor        cls.ctor = function() end    end    cls.new = function(...)        local instance        if cls.__create then            instance = cls.__create(...)        else            instance = {}        end        setmetatableindex(instance, cls)        instance.class = cls        instance:ctor(...)        return instance    end    cls.create = function(_, ...)        return cls.new(...)    end    return clsend
View Code

 

 

Lua-面向对象中类的构造