基类:基类定义了所有对于派生类来说普通的属性和方法,派生类从基类继承所需的属性和方法,且在派生类中增加新的属性和方法。

继承:继承是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中基类和“继承机制”的更多相关文章

  1. C++中基类虚析构函数的作用及其原理分析

    虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调 ...

  2. C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}

    C/C++:一个基类继承和多个基类继承的区别 1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性, ...

  3. Python的程序结构[2] -> 类/Class[1] -> 基类与继承

    基类与继承 / Base Class and Inheritance Class 面向对象的特性使得 Python 中不可避免地需要使用到类和类的继承,类的继承可以使得代码很好的被重用.下面以一些代码 ...

  4. 详解C++中基类与派生类的转换以及虚基类

    很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...

  5. C++中基类的析构函数为什么要用virtual虚析构函数

    知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...

  6. 【转载】Lua中实现类的原理

    原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...

  7. 关于Python中的类普通继承与super函数继承

    关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...

  8. c#中判断类是否继承于泛型基类

    在c#中,有时候我们会编写类似这样的代码: public class a<T> { //具体类的实现 } public class b : a<string>{} 如果b继承a ...

  9. 关于Java中基类构造器的调用问题

    在<Java编程思想>第7章复用类中有这样一段话,值得深思.当子类继承了父类时,就涉及到了基类和导出类(子类)这两个类.从外部来看,导出类就像是一个与基类具有相同接口的新类,或许还会有一些 ...

随机推荐

  1. jquery动态合并表格行

    利用<td rowspan = "num"/>;原理来实现,其中num为要合并的行数. <!DOCTYPE html> <html> <h ...

  2. 带蒙版的提交loading页面实现

    废话不多说,直接上代码. 首先是HTML中层的实现: <!-- loading 层 --> <div id="loadingDivBack" style=&quo ...

  3. java模拟浏览器上传文件

    public static void main(String[] args) { String str = uploadFile("C:/Users/RGKY/Desktop/wKgBHVb ...

  4. js 固话正则

    var str = '82386012'; var partten = /(^(0\d{2})-(\d{8})$)|(^(0\d{3})-(\d{7})$)|(^(0\d{2})-(\d{8})-(\ ...

  5. 从源代码剖析Mahout推荐引擎

    转载自:http://blog.fens.me/mahout-recommend-engine/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pi ...

  6. QuartZ2D __ 简单用法 1

    一. 简单做一个画板 1. 建立一个UIView类 2. 在.m里建立一个延展 3. 分别定义一个起点, 一个终点的结构体属性 . 在建立一个存储路径的数组 @interface DrawView ( ...

  7. popupwindow的基本使用以及基本动画效果

    1.创建一个popupwindow view的布局文件自己写一个就好了,这里就不说了 View view= LayoutInflater.from(context).inflate(R.layout. ...

  8. angular之上滑换页指令

    healthmallDirectives.directive("goodsTopRefresh", ['$window',function ($window) { return { ...

  9. Coming

    Hi,there, I am coming here to keep a great habit-one day a blog to share what new I have learned tod ...

  10. PHP 汉字拼音互转

    <?PHP function Pinyin($_String, $_Code='gb2312'){ $_DataKey = "a|ai|an|ang|ao|ba|bai|ban|ban ...