Chapter 16_3 多重继承
在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 多重继承的更多相关文章
- EFFECTIVE OBJECTIVE-C 2.0 TIPS 总结 CHAPTER 1 & CHAPTER 2
下面只是对读到的所有 Tips 结合我平时开发中遇到的问题进行总结,每一个 Tips 和书中的每一条对应,本文的目的是去掉书中的大部分讨论的内容,让人能够马上使用这些 Tips,建议阅读过原书后食用更 ...
- J a v a 的“多重继承”
接口只是比抽象类“更纯”的一种形式.它的用途并不止那些.由于接口根本没有具体的实施细节——也就是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起.这一点是至关重要的 ...
- Modern C++ CHAPTER 2(读书笔记)
CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...
- java提高篇(九)-----实现多重继承
多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需 ...
- 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类
[源码下载] 不可或缺 Windows Native (22) - C++: 多重继承, 虚基类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 多重继承 虚基类 示例1 ...
- scala 学习笔记(06) OOP(下)多重继承 及 AOP
一.多继承 上篇trait中,已经看到了其用法十分灵活,可以借此实现类似"多重继承"的效果,语法格式为: class/trait A extends B with C with D ...
- Effective C++ -----条款40:明智而审慎地使用多重继承
多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. virtual继承会增加大小.速度.初始化(及赋值)复杂度等等成本.如果virtual base classes不带任何 ...
- python基础——多重继承
python基础——多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗: Bat ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper
前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...
随机推荐
- 面向对象UML中类关系
如果你确定两件对象之间是is-a的关系,那么此时你应该使用继承:比如菱形.圆形和方形都是形状的一种,那么他们都应该从形状类继承而不是聚合.如果你确定两件对象之间是has-a的关系,那么此时你应该使用聚 ...
- DOM小解
现在来说说DOM 文档对象模型DOM(Document Object Model)定义访问和处理html文档的标准方法.DOM将html文档呈现为带有元素 ,属性和文本的树结构(节点树) 先来看看 ...
- iOS开发系列-UI基础-KVC
这些知识是UI初级学习的,目前我还在学习中,适合初学者看 KVC—Key Value Coding 也就是键值编码 是一种获取值和设置值的方式 当我们创建一个类文件,为这个类设置成员属性的时候: 创建 ...
- Struts2的DMI跟SMI
我使用的Struts2的版本是2.5.2,今天在使用Struts2的DMI(动态方法调用)的时候出现了一个有趣的问题,我先把我的配置及代码展示一下: web.xml <filter> &l ...
- centos7.0 vsftp配置
7.0版本 1.安装 yum -y install vsftpd 2.配置 vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO //设定不允许匿名访问 loc ...
- tabbar颜色与文字大小,状态栏样式
tabbar文字颜色与大小 [self.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor wh ...
- docker命令和后台参数
Docker官方为了让用户快速了解Docker,提供了一个 交互式教程 ,旨在帮助用户掌握Docker命令行的使用方法. Docker 命令行 下面对Docker的命令清单进行简单的介绍,详细内容在后 ...
- C#学习心得,记录学习
- bash脚本退出代码解释
Exit Codes With Special Meanings Table E-1. Reserved Exit Codes Exit Code Number Meaning Example Com ...
- 路由页面缓存开启 以及 keep-alive 给你埋下的坑
为什么要用keep-alive呢, 因为这个会缓存dom模板, 下次再回到这个页面, 就可以利用这个已经渲染好的dom结构了, 如果数据不一样, 也会启用 virtualDoM 进行diff更新, 这 ...