[cocos2dx]cocos2dx-lua中class语法

来源:互联网 发布:win10电脑动态桌面软件 编辑:程序博客网 时间:2024/04/29 04:57

在lua中,可以通过元表来实现类、对象、继承等。与元表相关的方法有setmetatable()、__index、getmetatable()、__newindex

关键:实现Lua面向对象可以分解为类的定义和类的实例化两个问题。类的定义主要是实现继承,即怎么让子类拥有父类的方法集类的实例化需要解决实例如何共享类的方法集,但独享自己的成员变量实例
方案:子类在定义时复制所有基类的方法,在实例化时将该类作为metatable的__index赋值给实例。这就是cocos2dx里面的lua class的实现。

function clone(object)--clone函数  local lookup_table = {}--新建table用于记录  local function _copy(object)--_copy(object)函数用于实现复制    if type(object) ~= "table" then       return object   ---如果内容不是table 直接返回object(例如如果是数字\字符串直接返回该数字\该字符串)    elseif lookup_table[object] then      return lookup_table[object]--这里是用于递归滴时候的,如果这个table已经复制过了,就直接返回    end    local new_table = {}    lookup_table[object] = new_table--新建new_table记录需要复制的二级子表,并放到lookup_table[object]中.    for key, value in pairs(object) do      new_table[_copy(key)] = _copy(value)--遍历object和递归_copy(value)把每一个表中的数据都复制出来    end    return setmetatable(new_table, getmetatable(object))--每一次完成遍历后,就对指定table设置metatable键值  end  return _copy(object)--返回clone出来的object表指针/地址end--[[clone  深度克隆一个值。格式:value = clone(值)用法示例:-- 下面的代码,t2 是 t1 的引用,修改 t2 的属性时,t1 的内容也会发生变化local t1 = {a = 1, b = 2}local t2 = t1t2.b = 3    -- t1 = {a = 1, b = 3} <-- t1.b 发生变化 -- clone() 返回 t1 的副本,修改 t2 不会影响 t1local t1 = {a = 1, b = 2}local t2 = clone(t1)t2.b = 3    -- t1 = {a = 1, b = 2} <-- t1.b 不受影响--]]--Create an class.function class(classname, super)--super为继承的类    local superType = type(super)    local cls    --如果父类既不是函数也不是table则说明父类为空    if superType ~= "function" and superType ~= "table" then        superType = nil        super = nil    end    --如果父类的类型是函数或者是C对象    if superType == "function" or (super and super.__ctype == 1) then        -- inherited from native C++ Object        cls = {}        --如果父类是表则复制成员并且设置这个类的继承信息        --如果是函数类型则设置构造方法并且设置ctor函数        if superType == "table" then  --复制基类变量            -- copy fields from super            for k,v in pairs(super) do cls[k] = v end            cls.__create = super.__create            cls.super    = super        else            cls.__create = super            cls.ctor = function() end        end        --设置类型的名称        cls.__cname = classname        cls.__ctype = 1        --定义该类型的创建实例的函数为基类的构造函数后复制到子类实例        --并且调用子数的ctor方法        function cls.new(...)  --实例化            local instance = cls.__create(...)            -- copy fields from class to native object            for k,v in pairs(cls) do instance[k] = v end            instance.class = cls            instance:ctor(...)            return instance        end    else        --如果是继承自普通的lua表,则设置一下原型,并且构造实例后也会调用ctor方法        -- inherited from Lua Object        if super then            cls = {}            setmetatable(cls, {__index = super})            cls.super = super        else            cls = {ctor = function() end}        end        cls.__cname = classname        cls.__ctype = 2 -- lua        cls.__index = cls        function cls.new(...)  --实例化            local instance = setmetatable({}, cls)            instance.class = cls            instance:ctor(...)            return instance        end    end    return clsend
通过该方法,我们可以很方便的定义一个class、继承一个class

--声明一个类:MyClass = class("MyClass")  function MyClass:ctor()      print("MyClass:ctor()")  end  --定义一个对象  local myclass = MyClass:new()  --继承一个类:--继承一个函数GameLayer = class("GameLayer", function()local layer = cc.Layer:create() return layer end)  local gamelayer = GameLayer:new()

ctor=constructor(构造函数)
dtor=destructor(析构函数)

1.在子类构造函数ctor()中要调用父类构造函数ctor(),这用self.super:ctor(param),这句话反应出并不会像C++那样,在创建子类实例时,自动调用父类的构造函数。
2.使用class(classname,super)来子类继承父类只会继承父类的成员函数,而不会继承父类的成员变量。

若要子类既要继承父类的成员函数也要继承父类的成员变量,且在创建子类实例时,自动调用父类的构造函数。这用下面的class(classname,super)

function class(classname, super)        local cls = {}    if super then        cls = {}        for k,v in pairs(super) do cls[k] = v end        cls.super = super    else        cls = {ctor = function() end}    end    cls.__cname = classname    cls.__index = cls    function cls.new(...)        local instance = setmetatable({}, cls)        local create        create = function(c, ...)             if c.super then -- 递归向上调用create                  create(c.super, ...)             end             if c.ctor then                  c.ctor(instance, ...)             end        end        --create(instance, ...)--若替换成instance:ctor(...)则先调用自己的构造函数,若自己没有,则调用父类的构造函数        instance:ctor(...)        instance.class = cls        return instance    end    return clsendlocal BaseClass = class("BaseClass", nil)function BaseClass:ctor(param)     print("baseclass ctor")     self._param = param     self._children = {}endfunction BaseClass:addChild(obj)     table.insert(self._children, obj)     for k,v in ipairs(self._children) do        print(k,v)     endendlocal DerivedClass = class("DerivedClass", BaseClass)function DerivedClass:ctor(param)     print("derivedclass ctor")endlocal instance = DerivedClass.new("param1")instance:addChild("child1")--打印输出--baseclass ctor--derivedclass ctor--1 child1
极具有参考价值的文章:Lua 面向对象实现

扩展阅读:Lua的面向对象程序设计 

0 0
原创粉丝点击