Lua类和类继承实现
Lua本身是不能像C++那样直接实现继承,但我们可以用万能的table表来实现。
以下我总结了三种方式的类以及继承的实现
第一、官方的做法,使用元表实现 原理参照《Programming in lua》
Object.lua
Object = {class_id = 0} function Object:new(o) o = o or {} setmetatable(o,self) -- 对象o调用不存在的成员时都会去self中查找,而这里的self指的就是Object self.__index = self return o end
---以下我们创建对象来测试以下
local o1 = Object:new()
o1.class_id = 11;
local o2 = Object:new()
o2.class_id = 22;
以上我们就利用元表实现了一个类,但这个类没有任何行为,以下我们继承上面的类
DisplayObject.lua
DisplayObject = Object:new() -- 现在为止,DisplayObject只是Object的一个实例,注意以下代码 D = DisplayObject:new(width = 100,height = 50) -- DisplayObject从Object继承了new方法,当new执行的时候,self参数指向DisplayObject。所以,D的metatable是DisplayObject,__index 也是DisplayObject。这样,D继承了DisplayObject,后者继承了Object。 ---在Lua中面向对象有趣的一个方面是你不需要创建一个新类去指定一个新的行为。
第二、复制表方式
我们同样使用上面的Object,换种写法
--Lua中的面向对象 --[[ 复制表方式面向对象 参数为一张表,通过遍历这张表取值,赋给一张空表,最后返回新建的表,来达到克隆表 ]] function cloneTab(tab) local ins = {} for key, var in pairs(tab) do ins[key] = var end return ins end
Object = {class_id = 1}
function Object.new()
local o = cloneTab(Object)
return o
end
-- 使用这个类
local p = Object.new()
继承实现
DisplayObject.lua
--[[ 复制表 第一参数是目标表,第二个参数是需要复制的表 通过遍历tab来取值将它赋值到目标表中 ]] function copy(dist,tab) for key, var in pairs(tab) do dist[key] = var end end DisplayObject = {} function DisplayObject.new() local ss = Object.new() copy(ss,DisplayObject) return ss end
local p1 = DisplayObject.new()
第三,使用函数闭包的形式实现面向对象
--以函数闭包的形式实现面向对象 --定义一个方法,函数闭包实现一个类的概念 function People(name) local self = {} --初始化方法,私有的 local function init() self.name = name end self.sayHi = function () print("Hello "..self.name) end --调用初始化 init() return self end --实例化一个对象 local p = People("ZhangSan") p:sayHi() --函数闭包的形式实现类继承 function Man(name) local self = People(name) -- local function init() -- -- end self.sayHello = function () print("Hi "..self.name) end return self end local m = Man("Lisi") --m:sayHello() m:sayHi()
PS;关于继承类,cocos2d-x v3版本提供一个更好更便捷的方式来实现。使用class全局方法创建
如
require "Object" GameObject = class("GameObject",function () return Object:new() end) function GameObject:create() return GameObject.new() end
-- 以上就实现了一个继承过程
在cocos引擎源代码下有extern.lua这个文件,里面就声明了class这个方法
extern.lua
function clone(object) local lookup_table = {} local function _copy(object) if type(object) ~= "table" then return object elseif lookup_table[object] then return lookup_table[object] end local new_table = {} lookup_table[object] = new_table for key, value in pairs(object) do new_table[_copy(key)] = _copy(value) end return setmetatable(new_table, getmetatable(object)) end return _copy(object) end --Create an class. function class(classname, super) local superType = type(super) local cls if superType ~= "function" and superType ~= "table" then superType = nil super = nil end if superType == "function" or (super and super.__ctype == 1) then -- inherited from native C++ Object cls = {} 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 end cls.ctor = function() end cls.__cname = classname cls.__ctype = 1 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 -- inherited from Lua Object if super then cls = clone(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 cls end function schedule(node, callback, delay) local delay = cc.DelayTime:create(delay) local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback)) local action = cc.RepeatForever:create(sequence) node:runAction(action) return action end function performWithDelay(node, callback, delay) local delay = cc.DelayTime:create(delay) local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback)) node:runAction(sequence) return sequence end