Lua实现OOP框架
2019-02-17 17:34
190 查看
Lua实现OOP框架
或许很多人在求职或者工作的过程中都会遇到类似,如何通过一个本身不支持OOP结构的语言来实现一个OOP结构的方案,在此整理了被人的一些实现方法
实现思路
基于Lua中table的元表metatable来实现
语法糖
在实现类结构之前需要先了解Lua中的语法糖:
Lua中的函数都是有self传递进去的,相当于C++中的this
例如
local a = { x = 99 }
– 打印函数,注意这里要访问表a中的变量x,必须指明self.x或者a.x,不然会报错
function a:Print()print("function a:test() " ..self.x) end
– 想调用a的Print()函数,我们可以这样写,注意参数是a,否则调用出错
a.Print(a)
– 也可以这样写,即用:代替. 且不用传入参数a
a:Print()
可以理解为通过":"调用的话,默认会有self作为参数传递,且此方法更为简便
Lua实现OOP的原理
当访问Lua表中不存在的元素的时候,会触发Lua的一套查找机制
举例说明:
test = { } -- 访问表test中不存在的变量a print(test.a)
此时的打印结果为nil,原因为test表中没有元素a,且test表没有元表metatable
元表可以理解为一个备用查找表,假设表A的元表为B,那么在A中找不到的东西就会在B中继续查找
举例说明:
-- 表A A = { } -- 表B B = { a = 99 } -- 给表B的元方法__index进行赋值 B.__index = B -- 设置表B为表A的元表 setmetatable(A,B) -- 再访问表A中不存在的变量a print(A.a)
打印结果为:99
查找过程:访问A.a时,先查看A表中是否有元素a,发现没有,但是发现A表有元表为B,则通过元表B的__index方法去查找,上述例子为B把自身赋值为自身的__index,如果__index为一个函数则调用函数获得其返回值,例子如下
-- 表A A = { } -- 表B B = { a = 99 } -- 给表B的元方法__index进行赋值,这里赋值为一个函数 B.__index = function(table, key) print("在元表中访问了变量"..key) return 88 end -- 设置表B为表A的元表 setmetatable(A,B) -- 再访问表A中不存在的变量a print(A.a)
打印结果:
在元表中访问了变量a
88
总结元表的查找顺序
步骤1.在表中查找,如果找到,返回该元素,找不到则继续步骤2
步骤2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续步骤3
步骤3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复步骤1、2、3;如果__index方法是一个函数,则调用该函数,并返回该函数的返回值
面向对象的封装
-- 类Class的声明,其实就是个table,这里有两个成员变量x,y Class = { x = 1, y = 2 } -- 设置metatable的元方法__index,指向表Class自己 Class.__index = Class -- 构造函数,叫什么名字无所谓,这里采用了C++的new名字 function Class:new(x, y) print("Class:模拟构造函数new()") -- 新建一个对象,这样通过Class:new()函数创建的每一个实例都是独立的 local tempObj = {} tempObj.x = x tempObj.y = y -- 设置新对象的metatable,谨记:这一步非常重要 setmetatable(tempObj,Class) -- 返回这个新创建的对象 return tempObj end -- 类的其他成员函数1 function Class:Print() print("Class:Print()") print("x = "..self.x..", y = "..self.y) end
面向对象的继承和多态
-- 子类SubClass的声明,这里又声明了一个新的变量z SubClass = { z = 0 } -- 设置元表为Class setmetatable(SubClass, Class) -- 设置metatable的元方法__index,指向表SubClass自己 SubClass.__index = SubClass -- 构造函数 function SubClass:new(x,y,z) print("模拟构造函数:SubClass") -- 先调用父类的构造函数,构造出一个父类的实例 local tempObj = Class:new(x,y) -- 将该对象的元表指向SubClass,谨记:这步非常重要,一定不要弄错了,是SubClass setmetatable(tempObj,SubClass) -- 新属性z赋值,有了子类自己的数据,这样就是子类实例了 tempObj.z = z return tempObj end -- 定义一个新的成员函数 function SubClass:SubPrint() print("SubClass:SubPrint() x = "..self.x..", y = "..self.y..", z = "..self.z) end -- 重定义父类的函数Add(),注意:和父类的不同,这里是增加了2倍的val function SubClass:Add(val) print("SubClass:Add()") self.x = self.x + 2*val self.y = self.y + 2*val end
参考https://blog.csdn.net/yzf279533105/article/details/80099358
相关文章推荐
- lua oop[0]:实现基本的OO 框架
- Qomolangma实现篇(六):Qomo的OOP框架的实现技术
- 【COCOS2DX-LUA 脚本开发之八】不用CCHttpClient而转用quick-cocos2d-x或cocos2dx-LuaProxy的Lua框架实现Lua-Http网络交互!
- Qomolangma实现篇(六):Qomo的OOP框架的实现技术
- lua教程八----不用CCHttpClient而转用quick-cocos2d-x或cocos2dx-LuaProxy的Lua框架实现Lua-Http网络交互!
- 利用CEGUI和Lua实现框架
- 【COCOS2DX-LUA 脚本开发之八】不用CCHttpClient而转用quick-cocos2d-x或cocos2dx-LuaProxy的Lua框架实现Lua-Http网络交互!
- Qomolangma实现篇(六):Qomo的OOP框架的实现技术
- lua OOP实现对象的链式调用
- 利用CEGUI+Lua实现灵活的游戏UI框架
- 利用CEGUI和Lua实现框架
- LUA OOP编程实现方法
- lua实现OOP编程
- 【COCOS2DX-LUA 脚本开发之八】使用quick-cocos2d-x或cocos2dx-LuaProxy的Lua框架实现Lua-Http网络交互!
- 【COCOS2DX-LUA 脚本开发之八】不用CCHttpClient而转用quick-cocos2d-x或cocos2dx-LuaProxy的Lua框架实现Lua-Http网络交互!
- 基于改造后的NGUI与Lua实现的unity热更新框架(一)
- 利用CEGUI+Lua实现灵活的游戏UI框架(转)
- LUA OOP 单例模式实现的 一个 方案
- Qomolangma实现篇(六):Qomo的OOP框架的实现技术
- Android应用程序窗口(Activity)实现框架简要介绍和学习计划