在Lua中进行面向对象编程时有几种方法,上一小结介绍了一种使用__index元方法的做法。

下面要介绍另一种方法,可以在Lua中实现多继承.

  关键一点,在于用函数作为__index元字段。

  多重继承意味着一个类可以有多个基类。因此无法使用一个类中的方法来创建子类,而是需要定义一个特殊的函数来创建。

它的参数表示新类的所有基类。创建时它会设置元表中的__index元方法。而多重继承正是在这个__index元方法中完成的。

类和基类之间的关系不同于类和实例之间的关系。尤其是一个类不能同时作为其实例和子类的元表。

在下面的createClass例子中,将类作为其实例的元表,并创建了另一个table作为类的元表。

用之前的Account和新的一个类Named去实现createClass。

新的Named有两个方法,setname和getname

Named = {}
function Named:getname()
return self.name
end
function Named:setname(n)
self.name = n
end

创建新类的代码:

--在table plist中查找"k"
local function search(k , plist)
for i = , #plist do
local v = plist[i][k] --尝试第i个基类
if v then return v end
end
end function createClass(...)
local c = {} --新类
local parents = {...}
--类在其父类列表中的搜索方法
setmetatable(c ,{__index = function( t , k )
return search( k , parents)
end
}) --将'c'作为其实例的元表
c.__index = c --为这个新类定义一个新的构造函数
function c:new(o)
o = o or {}
setmetatable(o,c)
return o
end
return c --返回新类
end

假设要创建一个新类NameAccount,同时从Account和Named派生,那么只需要调用createClass:

NamedAccount = createClass(Account,Named)

如果要创建并使用实例:

account = NamedAccount:new{name  = "Paul"}    --创建实例
print(account:getname()) --> Paul --使用实例

首先Lua在account中找不到“getname”。就查找account中的元表__index字段。该字段为NamedAccount。它也没有“getname”。

所以Lua就找NamedAccount的__index,结果是一个函数。该函数先在Account中查找,再在Named中查找(找到就结束了)。

由于这项搜索具有复杂性,所以多重继承性能不如单一继承。

一个改进方法是将继承的方法复制到子类中:

setmetatable(c , {__index = function (t, k )
local v = search ( k , parents )
t[k] = v --保存下来,以备下次访问
return v
end})

一个缺点:当系统运行后就较难修改方法的定义,因为这些改变不会沿着继承向下传播。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

Chapter 16_3 多重继承的更多相关文章

  1. EFFECTIVE OBJECTIVE-C 2.0 TIPS 总结 CHAPTER 1 & CHAPTER 2

    下面只是对读到的所有 Tips 结合我平时开发中遇到的问题进行总结,每一个 Tips 和书中的每一条对应,本文的目的是去掉书中的大部分讨论的内容,让人能够马上使用这些 Tips,建议阅读过原书后食用更 ...

  2. J a v a 的“多重继承”

    接口只是比抽象类“更纯”的一种形式.它的用途并不止那些.由于接口根本没有具体的实施细节——也就是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起.这一点是至关重要的 ...

  3. Modern C++ CHAPTER 2(读书笔记)

    CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...

  4. java提高篇(九)-----实现多重继承

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...

  5. 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类

    [源码下载] 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 多重继承 虚基类 示例1 ...

  6. scala 学习笔记(06) OOP(下)多重继承 及 AOP

    一.多继承 上篇trait中,已经看到了其用法十分灵活,可以借此实现类似"多重继承"的效果,语法格式为: class/trait A extends B with C with D ...

  7. Effective C++ -----条款40:明智而审慎地使用多重继承

    多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. virtual继承会增加大小.速度.初始化(及赋值)复杂度等等成本.如果virtual base classes不带任何 ...

  8. python基础——多重继承

    python基础——多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗: Bat ...

  9. Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper

    前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...

随机推荐

  1. Openjudge-NOI题库-蛇形填充数组

    题目描述 Description 用数字1,2,3,4,...,n*n这n2个数蛇形填充规模为n*n的方阵. 蛇形填充方法为: 对于每一条左下-右上的斜线,从左上到右下依次编号1,2,...,2n-1 ...

  2. 专注VR/AR广告 ,内容感知广告公司Uru获80万美元投资

    随着AR/VR技术不断地跃进,越来越多的公司开始运用这项技术为消费者提供广告和营销信息.Uru是一家打造计算机视觉驱动内容广告的公司,专注于数字视频和VR/AR类似的沉浸式媒介,就在刚刚这家公司宣布完 ...

  3. 用CKEDITOR 做自助上传的解决方案2

    1,在plugins下新建文件夹 multiimg 2,创建文件plugin.js (function() { CKEDITOR.plugins.add("multiimg", { ...

  4. NET 2.0(C#)调用ffmpeg处理视频的方法

    另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...

  5. 显示hibernate的sql语句

    <property name="show_sql">true</property> <property name="format_sql&q ...

  6. Output\TEST.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.

    点击错误信息,跳转到了一个.sct文件:*.o (RESET, +First) 按照如下操作,也不能解决问题.对比别的工程,也没找出问题. "操作是: Options for Target ...

  7. Samba: Server setup..

    To make samba shard folder permission clear, there are 3 kind of permission need to be paid attentio ...

  8. Crazy-Links

    1. 数据模型 2. Admin Formset RED is customized class |- object |- AdminForm |- InlineAdminForm |- BaseFo ...

  9. UIView 和 CALayer 的区别和联系

    UIView是在/System/Library/Frameworks/UIKit.framework定义,也就是处于Cocoa Touch层. CALyer是在/System/Library/Fram ...

  10. Hibernate5--课程笔记5

    关联关系映射: 关联关系,是使用最多的一种关系,非常重要.在内存中反映为实体关系,映射到DB中为主外键关系.实体间的关联,即对外键的维护.关联关系的发生,即对外键数据的改变. 外键:外面的主键,即,使 ...