quick-cocos2dx让我们可以完全用lua写游戏,在游戏开发中面向对象的开发是必需的,lua是一种脚本语言,并没有类的概念,因此我们要做的是在lua中实现一个伪造的class概念便于游戏的开发
首先我们要理解lua是如何在一个表中查找变量
- 首先查找该表中是否有该变量, 如果有则找到,没有则继续2
- 查找该表的元表(metable)是否存在,如果不存在则返回nil, 否则则在元表中继续3
- 看元表中是否有__index
如果不存在则返回nil
如果__index是一个方法,则返回方法的返回值
如果__index是一个表, 则查找表中是否有该变量,继续1
根据以上思路,我们可以伪造出一个lua class的概念(代码参照quick-cocos2dx)
function class(classname, super) local superType = type(super) -- 定义一个cls表 local cls if superType ~= "table" then --如果superType不是table类型的,这个参数无效 superType = nil super = nil end if super then cls = {} --如果有super表, 则将cls的元表设置为一个__index指向super表的表 setmetatable(cls, {__index = super}) --可以通过当前表的super字段访问到super表 cls.super = super else --没有super,则创建一个空构造函数的表 cls = {ctor = function() end} end cls.__cname = classname --cls自己的__index指向自己 cls.__index = cls function cls.new(...) --把一个空表的元表设置为cls并返回 local instance = setmetatable({}, cls) instance.class = cls instance:ctor(...) return instance end return cls end
以下是测试代码
local BaseData = class("BaseData") function BaseData:ctor(str) print("BaseData ctor",str); self.str = str; end function BaseData:doSomething() print("BaseData doSomething",self.str) end function BaseData:doBase() print("BaseData doBase",self.str) end local FriendData = class("FriendData",BaseData) function FriendData:ctor(str) FriendData.super.ctor(self,str) print("FriendData ctor",str) end function FriendData:doSomething() print("FriendData doSomething",self.str) end local baseData = BaseData.new("base") baseData:doSomething() print("================================="); local friendData1 = FriendData.new("friend1") friendData1:doSomething() friendData1:doBase() print("================================="); local friendData2 = FriendData.new("friend2") friendData2:doSomething() friendData2:doBase()
运行结果
BaseData ctor base BaseData doSomething base ================================= BaseData ctor friend1 FriendData ctor friend1 FriendData doSomething friend1 BaseData doBase friend1 ================================= BaseData ctor friend2 FriendData ctor friend2 FriendData doSomething friend2 BaseData doBase friend2
ok, 通过一个class方法,抽象 继承 封装 多态等类的基础特性都实现了