首页 > 学院 > 开发设计 > 正文

cocos2dx-lua 对lua项目中class(sub,super)的理解

2019-11-09 18:27:13
字体:
来源:转载
供稿:网友
lua 模拟面向对象的继承通常是通过class方法,今天简析一下对class的理解,先例子local MyApp = class("MyApp", cc.load("mvc").AppBase)

这是MyApp里的一个方法继承语句,class方法内部两个参数,一个是新建类简称A ,另一个是A继承的父类的类简称B,这句代码可以使得生成的A类继承B类后返回名为MyApp的新的子类。 重点内容 问题,class方法是如何实现模拟lua继承的呢? class有三种继承情况, 1、第一种是继承一个方法,

local LogoScene = class("LogoScene", function() return cc.Scene:create()end)

2、第二种继承一个C语言原生类

local LogoScene = class("LogoScene", cc.Scene)

3、继承一个lua类

local LogoScene = class("LogoScene", {})

下面看一下面class的代码

function class(classname, ...) local cls = {__cname = classname} --这里可以看出lua的cocos模拟的class方法支持多继承 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)) --这里是class继承的第一种情况,继承一个方法(在子类new之前先执行的内建函数__create) 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 --如果super是一个方法,把super直接复制给内建函数__create cls.__create = super --下面是class的第二,第三种情况,当传过来的值是table类型的时候 --这里需要明确的一点是,在lua里table其实还分两种,一种是lua的table,另一种是c里转换过来的一种类型叫userTable,在用tolua++绑定cocos2dx引擎的时候,tolua++会为userTable类型的类在执行create方法的时候为其加入.isclass属性(大家可以用执行dump(cc.Layer)观察) elseif superType == "table" then --下面这种是第二种情况 --如果有.isclass这个值则说明是从c++转换过来的数据结构 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)); --这里可以看出这种继承了c结构的子类其实也只是执行子类之前执行了一个创建父类对象的方法 cls.__create = function() return super:create() end else --后面这个是第三种情况,子类是lua继承的父类也是lua,这里有另一个内建函数__supers,他的作用是存放父类数组(父类可能不止一个) -- 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 --__index方法是一个“操作指南” --下面的__index对于继承功能的模拟也很关键 --更简单的说就是在我调用方法的时候,class是如何实现继承功能的(当子类搜索自己的函数未果,就会按照__index的指引去搜索父类,去寻找方法) 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 --这里的new方法是模拟cocos2dx里面的创建对象,下面的代码一目了然 cls.new = function(...) local instance if cls.__create then --这里需要注意的一件事是, -- --local LogoScene = class("LogoScene", function(argu) -- --dump(argu) -- return cc.Scene:create() --end) --function LogoScene:ctor(argu) -- --dump(argu) --end --上面的和这个栗子如果调用 LoginScene:create(argu)方法会将argu里的参数传到class后面的function里面,执行完function之后再执行ctor。 instance = cls.__create(...) else instance = {} end setmetatableindex(instance, cls) instance.class = cls instance:ctor(...) return instance end --这里只是为了模拟cocos2dx的编程习惯 cls.create = function(_, ...) return cls.new(...) end return clsend

到这里class的基本用法就写完了,usertable找个数据结构涉及到lua虚拟机内部的结构,后面研究透彻之后会继续补充。

2017.2.6
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表