关于Lua中的面向对象实现
写在前面
- 最近在琢磨“Lua热重载”,在测试中发现我之前对Lua中的面向对象实现有一些理解发生变化,这里记录一下。
- 本文提到的面向对象实现来自云风。
类实现
- 《Lua程序设计(第4版)》以银行账户存取钱为例,解释了如何实现一个类。从“面向对象的3大特性”角度,它的实现概括如下:
- 继承:改__index引向自己
- 多态:不用新建其他类,会自动找到对应方法(多重继承,书上举例是用查找父类方法实现的)
- 封装:
- 单方法:将公开的字段和函数放在单独表中;不过这种方式不能“继承”。
- 对偶:把表当key存起来;可“继承”。
- 不过《Lua程序设计(第4版)》书上没有完整的可直接拷走的代码,我工作项目用的是toLua,toLua也没有提供Lua类脚本,所以用了云风设计的class代码,如下:
local _class={}
function class(super)
local class_type={}
class_type.ctor=false
class_type.super=super
class_type.new=function(...)
local obj={}
do
local create
create = function(c,...)
if c.super then
create(c.super,...)
end
if c.ctor then
c.ctor(obj,...)
end
end
create(class_type,...)
end
setmetatable(obj,{ __index=_class[class_type] })
return obj
end
local vtbl={}
_class[class_type]=vtbl
setmetatable(class_type,{__newindex=
function(t,k,v)
vtbl[k]=v
end
})
if super then
setmetatable(vtbl,{__index=
function(t,k)
local ret=_class[super][k]
vtbl[k]=ret
return ret
end
})
end
return class_type
end
理解
- 对比:有对比才能看出云风写的class好在哪,之前我在看LuaFramework_UGUI框架时,它有一个写的很短很简单的LuaClass(如下),拿LuaClass和云风的对比,能看得出来LuaClass在“面向对象的3大特性”上没有实现“多态”和“封装”,LuaClass仅能作为参考,是不能直接搬到正式工程里用的。
--Author : Administrator
--Date : 2014/11/25 --声明,这里声明了类名还有属性,并且给出了属性的初始值。
LuaClass = {x = 0, y = 0} --这句是重定义元表的索引,就是说有了这句,这个才是一个类。
LuaClass.__index = LuaClass --构造体,构造体的名字是随便起的,习惯性改为New()
function LuaClass:New(x, y)
local self = {}; --初始化self,如果没有这句,那么类所建立的对象改变,其他对象都会改变
setmetatable(self, LuaClass); --将self的元表设定为Class
self.x = x;
self.y = y;
return self; --返回自身
end --测试打印方法--
function LuaClass:test()
logWarn("x:>" .. self.x .. " y:>" .. self.y);
end --endregion
- 回到class,最开始阅读class代码时,我有好些地方没看懂,包括“_class是放什么的”,“class_type为什么要起名叫class_type”等等。最近在琢磨“Lua热重载”时,再次回顾了这里,对以前理解错误的地方或是一知半解的问题有了新回答。以下是我在阅读时冒出的问题和对应回答:
- _class是什么?——> _class是记录各种类的类型(以下都称为“类-原型”)的词典(如果是我,会起名为_classTypeMap,这样更好懂)。
- 比如:新建两个类-原型A和B,此时_class中会记有类-原型A和类-原型B。
- _class是什么?——> _class是记录各种类的类型(以下都称为“类-原型”)的词典(如果是我,会起名为_classTypeMap,这样更好懂)。
local A = class()
local B = class()
- class()到底做了什么?——> class()其实负责的是创建“类-原型”,而非“类-实例”,这从它最后return的值是class_type可以看出。如果需要创建“类-实例”,就得用new函数。
- 下面的代码是什么意思?——> vtbl 即value table,setmetatable这里对class_type有写操作,却无读操作,即class_type里的数据是只写属性,即这些数据仅限于类内部使用。
local vtbl={}
_class[class_type]=vtbl
setmetatable(class_type,{__newindex=
function(t,k,v)
vtbl[k]=v
end
})
有需要的话,可以修改,例如下方就是把原来的只写属性改为可读可写属性,即public:
local vtbl = {}
_class[class_type] = vtbl
setmetatable(class_type, {
__newindex = function(t,k,v)
vtbl[k] = v
end,
__index = vtbl,
})
- 下面的代码是什么意思?——> 查找自己没有的数据时,如果有父类super,先去_class里找类-原型super的数据,拿该数据覆盖/填充
if super then
setmetatable(vtbl,{__index=
function(t,k)
local ret=_class[super][k]
vtbl[k]=ret
return ret
end
})
end
- 根据上面回答,以下是我加了注释的class代码:
-- https://blog.codingnow.com/cloud/LuaOO
-- 类(注释版) -- _class是记录各种类的类型(以下都称为“类-原型”)的词典
-- 比如:local A = class(),local B = class(),则_class中会记有类-原型A和类-原型B
-- 如果是我,会起名为_classTypeMap,这样更好懂
local _class = {} function class(super)
-- 创建的是类-原型class_type,只有用了类-原型的new函数,才能得到类-实例
local class_type = {}
-- 自定义构造函数ctor
class_type.ctor = false
class_type.super = super
class_type.new = function(...)
local obj = {}
do
local create = function(c, super)
if c.super then
create(c.super, ...)
end
if c.ctor then
c.ctor(obj, ...)
end
end
create(class_type, ...)
end
-- 在_class中查找类-类型为class_type的数据
setmetatable(obj, {__index = _class[class_type]})
return obj
end -- vtbl即value table
local vtbl = {}
_class[class_type] = vtbl
-- 对class_type有写操作,却无读操作,即class_type里的数据是只写属性,即这些数据仅限于类内部使用
-- (可见《Lua程序程序设计(第4版)》第21章“面向对象编程”的“对偶”)
setmetatable(class_type,
{
__newindex = function(t, k, v)
vtbl[k] = v
end }) -- 查找自己没有的数据时,如果有父类super,先去_class里找类-原型super的数据,拿该数据覆盖/填充
if super then
setmetatable(vtbl,
{
__index = function(t, k)
local ret = _class[super][k]
vtbl[k] = ret
return ret
end })
end return class_type end
关于Lua中的面向对象实现的更多相关文章
- Cocos2d-x 脚本语言Lua中的面向对象
Cocos2d-x 脚本语言Lua中的面向对象 面向对象不是针对某一门语言,而是一种思想.在面向过程的语言也能够使用面向对象的思想来进行编程. 在Lua中,并没有面向对象的概念存在,没有类的定义和子类 ...
- lua中的面向对象编程
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 上述代码会输出tb1 ~= tb2.说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的 ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- 【转载】【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
[游戏开发]在Lua中实现面向对象特性——模拟类.继承.多态 阅读目录 一.简介 二.前提知识 三.Lua中实现类.继承.多态 四.总结 回到顶部 一.简介 Lua是一门非常强大.非常灵活的脚本语 ...
- Lua中的面向对象编程详解
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 复制代码代码如下: local tb1 = {a = 1, b = 2}local tb2 = {a = 1, b ...
- lua 中的面向对象
lua 是一种脚步语言,语言本身并不具备面向对象的特性. 但是我们依然可以利用语言的特性,模拟出面向对象的特性. 面向对象的特性通常会具备:封装,继承,多态的特性,如何在lua中实现这些特性,最主要的 ...
- 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...
- Lua 中使用面向对象(续)
上一篇文章给了一个面向对象的方案,美中不足的是没有析构函数 Destructor,那么这一次就给它加上. 既然是析构,那么就是在对象被销毁之前做该做的事情,lua 5.1 的 userdata 可以给 ...
- Lua中的userdata
[话从这里说起] 在我发表<Lua中的类型与值>这篇文章时,就有读者给我留言了,说:你应该好好总结一下Lua中的function和userdata类型.现在是时候总结了.对于functio ...
- 9----Lua中的面向对象
什么是面向对象? 使用对象.类.继承.封装.消息等基本概念来进行程序设计 面向对象最重要的两个概念就是:对象和类 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位 一个对象由一组属性 ...
随机推荐
- javascript【基础】数据类型
五种基本数据类型 Number String Boolean Undefined 一个没有设置值的变量 Null 表示一个空对象引用 ES6(Symbol) //ES6 一种复杂数据类型 Object ...
- span服务器控件
Label Button 这些控件在服务器端都有对应的类可以去实例化一个对象, 可是像 span 这些在服务器没有对应的类可实例的, 在服务器端要实例化一个 span 控件时怎么办呢? 可以使用 Ht ...
- ORACLE之自治事务
在创建存储过程时,可以用关键字: PRAGMA AUTONOMOUS_TRANSACTION 创建自治事务. 常用场景: 触发器抛错导致事务回滚,日志的记录需要用自治事务进行记录 代码抛错,导致数据库 ...
- Office & WPS 基础篇
基础知识 安装office 推荐使用Microsoft Office,原因不详,不做讨论 使用Office tool plus安装,不要三年前版本,一般三年一代,工具自己找,版本文件自己找. 具体选项 ...
- maven-标准目录结构,常用命令,生命周期,概念模型图
maven-标准目录结构 作为一个maven工程,它的src目录和pom.xml是必备的,进入src目录后,我们发现它里面的目录结构如下: src/main/java -- 存放项目的 . java ...
- Jmeter 5.0 遇见connection reset问题
问题:大并发时遇见java.net.SocketException: Connection reset 测试过程中经常遇见connection reset ,原因是大数据量发送时,服务器不能接纳那么多 ...
- xlsx 前端导出Excel
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- centos7 七步教你安装搭建 LAMP 服务
先说说LAMP是什么 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写: Linux,操作系统 Apache,网页服务器 MariaDB或MySQL,数据库管理系统(或者数 ...
- 网络时间同步系统(NTP授时服务器)在电信网络的技术性应用研究
网络时间同步系统(NTP授时服务器)在电信网络的技术性应用研究 网络时间同步系统(NTP授时服务器)在电信网络的技术性应用研究 岳峰 15901092122 --------------------- ...
- labwindows excel 不同电脑上无法保存
存到c盘以外的盘,c盘因为权限问题可能无法写入