在lua中要实现对类的定义一般都是通过Metatable来做到的。。例如:
Fjs = {} function Fjs:new(name) local out = {} setMetatable(out,self) self.__index = self out.name = name return out end function Fjs:sayHello() print("my name is " .. self.name) print("hello") end local fjs = Fjs:new("fjs") fjs:sayHello()
首先定义了一个table,然后在它上面定义相应的方法,在创建对象的时候,通过将对象的Metatable指定为刚刚定义的table,这样也就实现了方法的绑定。。也就实现了类的定义和对象的创建。
上述实现中,自己需要定义一些约定的代码,在cocos2d-x中,为了实现的方便,扩展了一个class方法用于实现定义类型,对于上述类型的定义可以简化为如下:
Fjs = class("Fjs") function Fjs:ctor(name) self.name = name end function Fjs:sayHello() print("I am " .. self.name) print("hello") end fjs = Fjs.new("fjs") fjs:sayHello()
这个样子看起来简洁多了。。。这里定义了一个ctor方法,这个是构造函数
function class(classname,super) local superType = type(super) local cls --如果提供的super既不是函数,也不是table,那么就直接将super当做不存在 if superType ~= "function" and superType ~= "table" then superType = nil super = nil end --如果有提供super if superType == "function" or (super and super.__ctype == 1) then -- 定义一个table,它将作为类的定义 cls = {} --如果super是table,那么将super中定义的字段先全部拷贝到cls中 --然后将__create方法指定为super的__create方法 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 --这里提供的super时函数,那么也就是用这个方法来构造对象,那么直接将__create方法指向super cls.__create = super end --提供一个空的ctor构造函数 cls.ctor = function() end cls.__cname = classname cls.__ctype = 1 --定义.new(...)方法,他用户构建对象,首先是调用__create方法来构建一个table对象,然后将cls里面定义的字段全部拷贝到创建的对象中 --接下来在调用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的类型中继承 if super then cls = clone(super) cls.super = super else --直接就没有super,那么定义cls为一个带有空ctor的table cls = {ctor = function() end} end cls.__cname = classname cls.__ctype = 2 -- lua cls.__index = cls --这里的new方法,首先是创建了空的table,然后将其Metatable指向为cls --然后在调用ctor构造方法 function cls.new(...) local instance = setMetatable({},cls) instance.class = cls instance:ctor(...) return instance end end --返回类型的定义 return cls end
注释已经说的很明白了吧,我们接下来来分析一段常用的使用方式:
GameScene = class("GameScene",function() return cc.Scene:create() end) function GameScene:ctor() end function GameScene:create() return GameScene.new() end
这是比较常用的自定义Scene的方法,提供了create方法来具体的构建GameScene对象。。
通过上述class的代码,我们可以知道如下的执行步骤:
(1)首先用class中定义的super函数来构建了一个对象,也就是Scene:create()之后得到的scene对象
至于别的类型的定义,通过class代码的分析也能很容易的知道执行步骤