Chapter 16_1 Class
一个类就是一个创建对象的模具。对于一些基于原型的语言,对象是没有“类型”的,而是每个对象都有一个原型(prototype).
原型也是一种常规的对象。当其他对象(类的实例)遇到一个未知操作时,原型会先查找它。这种语言要创建一个类,只需要创建一个专用作其他对象的原型。
类和原型都是一种组织对象间共享行为的方式。
在Lua中,可以用继承实现原型。如果有两个对象a和b,要让b作为a的原型:
setmetatable(a, {__index = b})
在此之后,a就会在b中查找所有它没有的操作。将b称为是对象a的类,只不过是术语上的一个变化。
回到上面的Account例子中,为了创建更多与Account行为类似的账号,可以让这些新对象从Account行为中继承这些操作。
具体做法是使用__index元方法。可以用一项小优化,则无须创建一个额外的table作为账户对象的元表。而是使用Account table自身作为元素:
function Account:new(o)
o = o or {} --如果用户没有提供,就创建一个空表
setmetatable(o , self )
self.__index = self
return o
end
当调用Account:new时,self就等于Account。因此可以直接用Account代替self。
当引入类继承时,使用self则会更为准确。
a = Account:new(balance = )
a:deposit(100.00)
当创建新账号时,a会将Account作为元表,当调用a:deposit(100.00)时,就是调用了a.deposit(a, 100.00).
当Lua无法在table a中找到条目deposit时,会进一步搜索元表的__index条目。
getmetatable(a).__index.deposit(a, 100.00)
a的元表是Account,Account.__index也是Account。因此,上面的表达式可以简化为:
Account.deposit(a , 100.00)
结果为Lua调用了原来的deposit函数,但传入a作为self参数。因此新账号a从Account继承了deposit函数。
继承不仅可以作用于方法,也可以作用于所有其他在新账户中没有的字段。
比如上面的balance field。如果在创建新账户时没有提供balance的初值,那么它就会继承这个默认值。
b = Account:new()
print(b. balance) --> 0
在b上调用deposit时,self就是b,相当于:
b.balance = b.balance + v
在第一次调用deposit时,对b.balance的求值结果为0,然后一个初值被赋予了b.balance。
后续对b.balance的访问就不会再涉及到__index元方法了,因为此时b已有自己的balance字段。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》
Chapter 16_1 Class的更多相关文章
- Modern C++ CHAPTER 2(读书笔记)
CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- ApiWrapper
前面两片文章讲解了通过AIDL和Messenger两种方式实现Android IPC.而本文所讲的并不是第三种IPC方式,而是对前面两种方式进行封装,这样我们就不用直接把Aidl文件,java文件拷贝 ...
- Android Programming: Pushing the Limits -- Chapter 7:Android IPC -- Messenger
Messenger类实际是对Aidl方式的一层封装.本文只是对如何在Service中使用Messenger类实现与客户端的通信进行讲解,对Messenger的底层不做说明.阅读Android Prog ...
- [转]第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV
仅供参考,还未运行程序,理解部分有误,请参考英文原版. 绿色部分非文章内容,是个人理解. 转载请注明:http://blog.csdn.net/raby_gyl/article/details/174 ...
- 《深入理解计算机系统》 Chapter 7 读书笔记
<深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...
- 《Linux内核设计与实现》Chapter 3 读书笔记
<Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...
- PRML Chapter 2. Probability Distributions
PRML Chapter 2. Probability Distributions P68 conjugate priors In Bayesian probability theory, if th ...
- PRML Chapter 1. Introduction
PRML Chapter 1. Introduction 为了防止忘记,要把每章的重要内容都记下来,从第一章开始 2012@3@28 今天又回去稍微翻了一下第一章内容,发现第一次看的时候没有看透,每次 ...
- MathType 插入定义的chapter and section break后无法隐藏
每一章标题后面插入一个“Next Section Break”,这样定稿后各章文件组合为总文件后,方程编号会自动递增,如果已经插入了默认的“Equation Chapter 1 Section 1”, ...
随机推荐
- [转]Python跳过第一行读取文件内容
from itertools import islice file_name='XXXX' input_file = open(file_name) for line in islice(input_ ...
- PHPStorm 安装 SASS、SCSS + Compass
许久没更新博客啦,这两天研究了下 SASS 和 LESS ,最终选了 SASS,因为相对比较成熟些吧,试了很多坑之后,终于成功了,下面上步骤: 1. 安装 PHPStorm 的 SASS 插件 好像是 ...
- [DP之计数DP]
其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常 ...
- Gentoo网络管理方法总结
OpenRC/netifrc Netifrc is a collection of modules created to configure and manage network interfaces ...
- LINQ_to_SQL语法及实例大全
LINQ To SQL 语法及实例大全 2011/4/5 目录 LINQ to SQL语句(1)之Where. 2 Where操作... 2 1.简单形式:... 2 2.关系条件形式:... 2 3 ...
- [阿当视频]WEB组件学习笔记
— 视频看完了,自定义事件还不懂,等完全懂了再更新并完成整篇案例 1. JS分层和组件的种类浏览器底层包括HTML CSS JS(DOM/BOM/Style/Canvas 2D/WebGl/SVG) ...
- LeetCode #3. Longest Substring Without Repeating Characters C#
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- The Key to final data
// FinalData.java - (insert one line description here) package com.hp.ci.mgmt.perm.hal.localization; ...
- lucene 索引删除
1.IndexWriter和IndexReader都有删除索引的方法:deleteDocuments(); 不建议使用IndexReader删除索引:使用IndexReader进行删除时,必须关闭所有 ...
- 如何取消input记忆功能
默认情况下,input会有这个记忆功能,如果不想让它记忆,可以在input上加上autocomplete="off"即可.