Lua中的table就是一种对象,即它拥有状态、拥有独立于其值的标识(self)、table与对象一样具有独立于创建者和创建地的征集周期

什么叫对象拥有独立的生命周期?

Account = {balance = 0}

function Account.withdraw(v)
Account.balance = Acount.balance-v
end --则可进行如下调用 Account.withdraw(v) --[[在函数中使用全局名称Account不是个了习惯
因为这个函数只能针对特定对象使用(此例中
的Account,并且这个特定对象必须存储在特定
全局变量中,如果改变了对象名称,withdraw
就不工作了 a = Account;Account = nil
a.withdraw(100.00) --错误

这种行为违反了面向对象的特性,即对象拥有独立的生命周期,有一种灵活的方法即指定一项操作所用的“接者者”,因此需要一个额外的参数来表示该接受者。这个参数通常称为self或this


function Account.withdraw(self,v)
self.balance = self.balance - v
print(self.balance);
end

下面调用该方法,必须指定期作用对象

a1 = Account;Account = nil
a1.withdraw(a1,100.00) --100

self参数是所有面像对象语言的一个核心。大多数面向对象语言都能对程序员隐藏部分self参数。lua只需要用冒号则能隐藏该参数,即可重写为

Account = {balance = 0}
function Account:withdraw(v)
self.balance = self.balance - v
print(self.balance);
end a1 = Account;Account = nil
a1:withdraw(100.00) --100

16.1 类

lua实现原型是依赖于元表。如果两个对象a,b,要让b做为a的一个原型只需要输入以下语句:

setmetatable(a,{__index=b})

加到先前银行账号示例。为了创建更多与Accoun行为类似的账号(这里的类似指具有相同方法),可以让这些新对象从Account中继承这些操作。具体做法就是使用 __index元方法,可以应该一项小优化,则无须创建一个额外的table作为账号对象元表。而是使用Account table自身作为对象元表。

Account = {balance = 0,
withdraw = function(self,v)
self.balance = self.balance - v
print(self.balance);
end
} function Account:deposit(v)
self.balance = self.balance + v
print(self.balance);
end function Account:new(o)
o = o or {} --如果用户没有提供table则创建一个
setmetatable(o,self)
self.__index = self
return o
end a = Account:new{balance = 0}
a:deposit(100.00) --输出100

如上代码所示实际上table a 只有一个成员balance = 0,那它为什么调用deposit方法确成功了呢,这就是__index元方法的功能所在了。__index元方法在table找不到成员时会去寻找__index元方法所在的table里找方法。而这样就是lua继承的概念。

当创建新账户时,a会将Account作为其元表。而当调用a:deposit(10

--基类 Account
Account = {balance = 0}
function Account::withdraw(self,v)
self.balance = self.balance - v
print(self.balance);
end function Account:deposit(v)
self.balance = self.balance + v
print(self.balance);
end function Account:new(o)
o = o or {} --如果用户没有提供table则创建一个
setmetatable(o,self)
self.__index = self
return o
end --子类 SpecialAccount继承自 Account
SpecialAccount = Account:new() s = SpecialAccount:new{limit=1000.00} --s继承自SpecialAccount
s:deposit(100.00) --最终会在Account里找见deposit的实现 --SpecialAccount之所有特殊是因为可以重定义那些从基类继承来的方法,编写一个方法的新实现只需要
function SpecialAccount:withdraw(v)
if v - self.balance >= self:getLimit() then
error"insufficient funds"
end
self.balance = self.balance - v
end function SpecialAccount:getLimit()
return self.limit or 0
end --s表示一个特殊客户 这个客户透支额度总是其余额的10%,那么可以只修改这个对象
function s:getLimit()
return self.balance * 0.10
end

0.00)时,就调用了a.deposit(a,100.00),lua无法从table a中找到条目deposit,那么它会进一步寻找__元表__index的值。最终调用为

getmetatable(a).__index.deposit(a.100.00)

a的元表是Account,Account.__index 也是Account上面这个可以化简为:

Account.desposit(a,100.00)

继承不仅可以用作方面,也可以用作没有的字段 ,如下所示

b = Account.new()
print(b.balance) --0

16.2继承

lua面向对象编程 《lua程序设计》 16章 笔记的更多相关文章

  1. C#高级编程9 第16章 错误和异常

    C#高级编程9 第16章 错误和异常 了解这章可以学会如何处理系统异常以及错误信息. System.Exception类是.NET运行库抛出的异常,可以继承它定义自己的异常类. try块代码包含的代码 ...

  2. .net 4.0 面向对象编程漫谈基础篇读书笔记

    话说笔者接触.net 已有些年头,做过的项目也有不少,有几百万的,也有几十万的,有C/S的,也有B/S的.感觉几年下来,用过的框架不少,但是.net的精髓一直没有掌握.就像学武之人懂得各种招式,但内功 ...

  3. Lua面向对象编程

    Lua中的table就是一种对象,看以下一段简单的代码: , b = } , b = } local tb3 = tb1 if tb1 == tb2 then print("tb1 == t ...

  4. lua 面向对象编程类机制实现

    lua no class It is a prototype based language. 在此语言中没有class关键字来创建类. 现代ES6, 已经添加class类. prototype bas ...

  5. Java使用实现面向对象编程:第七章集合框架的解读=>重中之重

    对于集合框架,是非常重要的知识,是程序员必须要知道的知识点. 但是我们为什么要引入集合框架呢? 我们之前用过数组存储数据,但是采用数组存储存在了很多的缺陷.而现在我们引用了集合框架,可以完全弥补了数组 ...

  6. java 面向对象编程--第十四章 多线程编程

    1.  多任务处理有两种类型:基于进程和基于线程. 2.  进程是指一种“自包容”的运行程序,由操作系统直接管理,直接运行,有自己的地址空间,每个进程一开启都会消耗内存. 3.  线程是进程内部单一的 ...

  7. 【java并发编程实战】第一章笔记

    1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...

  8. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  9. java 面向对象编程 --第十二章 JDK常用类

    1.  系统类 java.lang包   System类 sys.out;sys.exit;sys.gc; sys.currentTimeMillis();----得到从1970-01-01到当前时间 ...

随机推荐

  1. [ThinkPHP] 从一个表中获得栏目对应的ID,从另一个表获得属于这些栏目的文章

    public function index(){ $cate = 1; $query = M('Cate')->field('id')->where(array('id'=>$cat ...

  2. HDU 6214 Smallest Minimum Cut 【网络流最小割+ 二种方法只能一种有效+hdu 3987原题】

    Problem Description Consider a network G=(V,E) with source s and sink t . An s-t cut is a partition ...

  3. 23、Flask实战第23天:Flask-Restful

    Restful API规范 restful api是用于前端和后台进行通信的一套规范.使用这个规范可以让前后端开发变得更加轻松. 协议 采用http或者https 数据传输格式 数据之间传输的格式应该 ...

  4. Centos7下安装7za 及7za常用命令

    安装必备环境 yum install kernel-devel kernel-headers gcc-c++ make bzip2 下载源码(16.02版本,2016.10.04 publish) w ...

  5. Joomla!网站扫描工具joomscan

    Joomla!网站扫描工具joomscan   Joomla!是一款知名的PHP语言编写的CMS系统.很多网站都使用Joomla!搭建而成.Kali Linux集成了一款Joomla!网站扫描工具jo ...

  6. URAL 2062 Ambitious Experiment(分块)

    [题目链接] http://acm.timus.ru/problem.aspx?space=1&num=2062 [题目大意] 给出两个操作,操作一给出区间[l,r],对l到r中的每一个下标i ...

  7. [AGC025E]Walking on a Tree

    题意:有一棵树,你要按顺序在树上走$m$次,每次从$u_i$到$v_i$或从$v_i$到$u_i$,走完后,如果一条边被单向经过,那么它贡献$1$的价值,如果一条边被双向经过,那么它贡献$2$的价值, ...

  8. 【分治】计算概论(A) / 函数递归练习(1)多边形游戏

    #include<cstdio> #include<algorithm> using namespace std; ],c[],s[]; int work(int L,int ...

  9. cocos2d-x 扩展 修改 备注

    1.引擎源码相关扩展     说明:class/cellsExt 下的全部文件为扩展文件,有auto字样的文件为生成文件,*.pkg文件为自动生成文件的接口配置档,参考tolua++,源文件中代在[s ...

  10. Android Studio 中修改versionCode跟versionName

    在Android Studio 中修改versionCode 跟versionName最写了一个新版的软件准备发布到应用平台上,但是versionCode和versionName的值一直修改不成功,在 ...