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文件拷贝 ...
随机推荐
- Ubuntu环境openresty的安装
Ubuntu环境openresty的安装 相关库的安装 安装openresty需要的库 apt-get install libreadline-dev libncurses5-dev libpcre ...
- html css jquery 回到顶部按钮
今天做了个回到顶部的功能,在这里记录一下,有需要可以拿去试试! CSS部分,很简单就一个class /*回到顶部*/ .back-top { position: fixed; right: 15px; ...
- 安卓平台 全面支持软解和硬解的SDK-Demo源代码开放
专业做视频编解码的SDK开发工作. 2015年12月1日10:46:55: 更新到1.5.0版本 功能列表: 基本播放: 1,正常播放, 支持MP4,FLV,AVI,TS,3GP,RMVB,WM,WM ...
- Interrupts
- linux/windows平台生成随机数的不同方法
linux平台,使用rand.Seed() //rand_linux.go package main import ( "math/rand" "time" ) ...
- webstorm for mac 破解步骤
第一步:Web storm下载--从官网下载就可以 第二步:下载 - Java for OS X 2015-001--https://support.apple.com/kb/DL1572?viewl ...
- js事件监听-addEventListener (w3c标准) 和 attachEvent(ie)
研究了一个小时,没看懂这两个属性 window.onload = function(){ var oDiv = document.getElementById("J_myDiv") ...
- PyCharm 安装指南
一.官网下载最新版的PyCharm,根据平台选择版本(Liunx,Windows) 地址:https://www.jetbrains.com/pycharm/download/#section=win ...
- wefwewewe
<a hred="https://www.baidu.com">dssf</a>
- sudo命令出错 must set be suid
特殊权限 4,2 ,1 4 suid,控制用户执行的文件,以文件所属用户的身份执行.当一个可执行的文件拥有suid时,会将文件拥有者的x位变成s(---s--x--x),这时称为set uid,简写 ...