lua中基类和“继承机制”
基类:基类定义了所有对于派生类来说普通的属性和方法,派生类从基类继承所需的属性和方法,且在派生类中增加新的属性和方法。
继承:继承是C++语言的一种重要机制,它允许在已定义的类的基础上产生新类。
lua基类和C++基类极为相似,但是lua中却没有继承这一说,更没有所谓的派生类。lua只能通过一种行为(元表)来模拟C++继承这一方法。
元表:lua中提供的元表是用于帮助lua数据变量完成某些非预定义功能的个性化行为,当它做某一种操作,然而self表中却没有定义实现这种操作的方法,那么为了实现这一操作便会去元表中找实现这一操作的方法。
如果每一层的元表都定义一种方法指向上一层要“继承”的lua表,这样是不是就和C++继承一样了,有木有!
元方法:C++中的继承不会改变语言的常规行为。但是lua中却提供了一种可以改变table行为的方法,有两种可以改变的table行为:(__index元方法)查询table及( __newindex元方法)修改table中不存在的字段
(1)__index元方法:当对元表中不存在的字段进行访问时,得到的结果为nil。通过定义这个元表的__index,那个访问结果将由这个方法决定。
这个方法也是“继承”父类的方法。
(2)__newindex元方法:当对元表中不存在的字段进行赋值时,解释器会先找到这个元表的__newindex,如果有就调用它,对__newindex指向的表进行赋值操作, 如果没有才对self表进行赋值。
--保存类类型的虚表
local _class = {} GLOBAL_OBJ_COUNT = {}
ENABLE_OBJ_COUNT = function FindClassName(target, depth)
for key,value in pairs(_G) do
if value == target then
return key
end
end
end function ClasCountRetain(c)
local key = FindClassName(c)
if GLOBAL_OBJ_COUNT[key] == nil then
GLOBAL_OBJ_COUNT[key] =
else
GLOBAL_OBJ_COUNT[key] = GLOBAL_OBJ_COUNT[key] +
end
end function ClasCountRelease(c)
local key = FindClassName(c)
if GLOBAL_OBJ_COUNT[key] == nil then
GLOBAL_OBJ_COUNT[key] = ---标识异常
else
GLOBAL_OBJ_COUNT[key] = GLOBAL_OBJ_COUNT[key] -
end
end function PrintLuaClassCount( ... )
print("PrintLuaClassCount.............")
for key,value in pairs(GLOBAL_OBJ_COUNT) do
print("PrintLuaClassCount:"..key..":",value)
end
end function BaseClass(super) -- 生成一个类类型
local class_type = {}
-- 在创建对象的时候自动调用
class_type.__init = false
class_type.__delete = false
class_type.super = super class_type.New = function(...) --定义New成员方法
-- 生成一个类对象
local obj = {}
obj._class_type = class_type -- 在初始化之前注册基类方法
setmetatable(obj, { __index = _class[class_type] }) -- 调用初始化方法
do
local create
create = function(c, ...)
if c.super then
create(c.super, ...) --对所有基类都进行init
end
if ENABLE_OBJ_COUNT ~= then
ClasCountRetain(c)
end
if c.__init then
c.__init(obj, ...)
end
end create(class_type, ...)
end -- 注册一个delete方法
obj.DeleteMe = function(self)
local now_super = self._class_type
while now_super ~= nil do
if ENABLE_OBJ_COUNT ~= then
ClasCountRelease(now_super)
end
if now_super.__delete then
now_super.__delete(self) --对所有基类都进行delete
end
now_super = now_super.super
end
end return obj
end local vtbl = {}
_class[class_type] = vtbl setmetatable(class_type, {__newindex =
function(t,k,v)
vtbl[k] = v --赋值操作时self找不到的字段则对vtbl表赋值
end
,
__index = vtbl, --For call parent method
}) if super then
setmetatable(vtbl, {__index = --元表做“继承”操作
function(t,k)
local ret = _class[super][k]
return ret
end
})
end return class_type
end
lua中基类和“继承机制”的更多相关文章
- C++中基类虚析构函数的作用及其原理分析
虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调 ...
- C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}
C/C++:一个基类继承和多个基类继承的区别 1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性, ...
- Python的程序结构[2] -> 类/Class[1] -> 基类与继承
基类与继承 / Base Class and Inheritance Class 面向对象的特性使得 Python 中不可避免地需要使用到类和类的继承,类的继承可以使得代码很好的被重用.下面以一些代码 ...
- 详解C++中基类与派生类的转换以及虚基类
很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...
- C++中基类的析构函数为什么要用virtual虚析构函数
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- 关于Python中的类普通继承与super函数继承
关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...
- c#中判断类是否继承于泛型基类
在c#中,有时候我们会编写类似这样的代码: public class a<T> { //具体类的实现 } public class b : a<string>{} 如果b继承a ...
- 关于Java中基类构造器的调用问题
在<Java编程思想>第7章复用类中有这样一段话,值得深思.当子类继承了父类时,就涉及到了基类和导出类(子类)这两个类.从外部来看,导出类就像是一个与基类具有相同接口的新类,或许还会有一些 ...
随机推荐
- 打开eclipse报错
隔了一段时间没用eclipse, 打开之后报错: 从报错上来看是因为java版本太低导致的. 我打开cmd, 运行java -version 后 发现java 版本已经更新到了1.8 然后就有点懵. ...
- C# List<T> 合并、去重、查找
List<,,,,,}; List<,,,,}; listA.AddRange(listB );//把集合A.B合并 List<int> Result = listA.Unio ...
- Linux中文件颜色所代表的属性和颜色
绿色文件: 可执行文件,可执行的程序 红色文件:压缩文件或者包文件 蓝色文件:目录 白色文件:一般性文件,如文本文件,配置文件,源码文件等 浅蓝色文件:链接文件,主要是使用ln命令 ...
- plsql配置远程连接数据库
1.先安装plsql.地址:http://pan.baidu.com/s/1hqGbATI 2. 解压缩 instantclient_11_2(这个客户端可以在网上找精简版的),找到以下路径 \i ...
- 【DWR系列03】- DWR主要类详解
img { border: 1px solid black } 一.简介 首先应该了解这个jar包主要的类,了解了类,就了解了DWR.DWR的在线javadoc:http://directwebrem ...
- Java并发集合的实现原理
本文简要介绍Java并发编程方面常用的类和集合,并介绍下其实现原理. AtomicInteger 可以用原子方式更新int值.类 AtomicBoolean.AtomicInteger.AtomicL ...
- AOJ 0558 Cheese【BFS】
在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次), ...
- git rebase 和 merge的区别
- 公共资源情报(OSINT)工具Automater
公共资源情报(OSINT)工具Automater 公共资源情报(OSINT)就是从公共信息中提取有用情报.它是美国中央情报局(CIA)的一种情报搜集手段,各国都在广泛利用这种方式.Kali Lin ...
- 在 Delphi 中判断一个字符是中文的方法
http://blog.163.com/l1_jun/blog/static/143863882011741124581/ 由于 Delphi2005 支持中文标识符,在编写 PASCAL 词法分析器 ...