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 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 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++中基类的析构函数为什么要用virtual虚析构函数
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- 关于Python中的类普通继承与super函数继承
关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...
- 关于Java中基类构造器的调用问题
在<Java编程思想>第7章复用类中有这样一段话,值得深思.当子类继承了父类时,就涉及到了基类和导出类(子类)这两个类.从外部来看,导出类就像是一个与基类具有相同接口的新类,或许还会有一些 ...
- 虚基类&;虚继承
发现这个月准备竞赛完全没有更新哎... 改了下某华大一c++测试题...网上对虚继承讲的要么太繁琐要么不到位,自力更生 #include<iostream> #include<fst ...
- c++中基类与派生类中隐含的this指针的分析
先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...
随机推荐
- Java的算数运算符、关系运算符、逻辑运算符、位运算符
JAVA的运算符,分为四类: 算数运算符.关系运算符.逻辑运算符.位运算符 算数运算符(9):+ - * / % ++ -- 关系运算符(6):== != > >= & ...
- JS 学习笔记--JS中的事件对象基础
事件:JavaScript中的事件是由访问web页面用户的一系列操作引起的,比如点击鼠标,键盘按键等.当用户执行某些操作的时候再去执行一些代码. 事件模型:内联模型.脚本模型.DOM2模型 内联模型: ...
- python 字典items和iteritems
3.4.6 items和iteritems 说明:items以列表方式返回字典中的键值对,iteritems以迭代器对象 返回键值对儿(Python3中不再支持): 例子: 1: >>&g ...
- windows phone 生产含logo的二维码
这几天了解二维码了解的比较多,不过就是没深入了解.google了一下生产含logo二维码的思路,就是把logo给画到生成的二维码上,还是因为二维码的纠错能力足够好啊,用Graphics对图片进行操作? ...
- ffmpeg, libav学习记录
转载自:http://hi.baidu.com/y11022053/item/81f12035182257332e0f8196 一个偶然遇到了ffmpeg,看起来不多,而且通用性很强,算是一个扎实的技 ...
- Android四大图片缓存(Imageloader,Picasso,Glide,Fresco)原理、特性对比
四大图片缓存基本信息 Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用. Picasso 是 Square 开源的项目,且他的主导者是 JakeWharton,所 ...
- poj1657---chessboard
对棋盘横纵坐标的解读 str1="f3" str2="e9" x=abs(str1[0]-str2[0]) y=abs(str1[1]-str1[1]) 如果x ...
- Angular ng-repeat 对象和数组遍历
直接上代码 <!DOCTYPE html> <html> <head> <meta name="description" content= ...
- linux libpcap的性能问题,请大家注意绕行。
内核代码中,ip_rcv是ip层收包的主入口函数,该函数由软中断调用.存放数据包的sk_buff结构包含有目的地ip和端口信息,此时ip层进行检查,如果目的地ip不是本机,且没有开启转发的话,则将包丢 ...
- [记录]Zabbix3.4配置监控Oracle12c的存活状态和表空间使用率
Zabbix3.4配置监控Oracle的存活状态和表空间使用率 1.安装zabbix3.4 agent: # rpm -ivh http://repo.zabbix.com/zabbix/3.4/rh ...