【Lua】面向对象编程(一)
类和对象:
account.lua
module(...,package.seeall)
Account={balance=0}
Account.new=function(self,o)
    local o=o or {}
    setmetatable(o,self)
    self.__index=self
    return o
end
Account.getBalance=function(self)
    return self.balance
end
Account.setBalance=function(self,money)
    self.balance=money
end
Account.withdraw=function(self,money)
    if money<0 then
    error("<Account.deposit> money must > 0")
    else
    if money > self.balance then
        error("<Account.deposit> no enough balance")
    end
    self.balance=self.balance-money
    end
end
Account.deposit=function(self,money)
    if money <0 then
    error("<Account.deposit> money must > 0")
    end
    self.balance=self.balance+money
end
Account.__tostring=function(self)
    str=os.date("%y/%m/%d %H:%M:%S",os.time())
    str=string.format("%s\nBalance:%s",str,self.balance)
    return str
end
注:
Lua检测到没有的字段时,但在其元表中有一个__index字段,那么Lua会调用这个__index元方法,并返回结果,__index元方法可以使函数或者是table,当元方法是一个函数时,Lua以table和不存在的key做为参数来调用该函数,当元方法是一个table时,Lua重新访问这个table。
上述代码,当调用Account:new 时,self等于Account,因此可以直接使用Account来代替self,当引入类的继承时,使用self更加准确。
继承:
specialAccount.lua
module(...,package.seeall)
SpecialAccount=MAccount.Account:new({limit=1000.0})
SpecialAccount.getLimit=function(self)
    return self.limit
end
SpecialAccount.withdraw=function(self,money)
    if money <0 then
    str="<SpecialAccount.withdraw> money must > 0"
    Logger:error(str)
    error(str)
    end
    if money > self:getLimit() then
    Logger:warn("<SpecialAccount.with> withdraw > limit")
    return
    end
    self.balance=self.balance-money
end
SpecialAccount.__tostring=function(self)
    str=string.format("%s\nLimit:%d",MAccount.Account.__tostring(self),self.limit)
    return str
end
说明:
SpecialAccount继承了Account的所有函数和变量,在执行SpecialAccount的new函数,它的self参数表示为SpecialAccount,因此执行以下语句:
s表示的元表为SpecialAccount,而SpecialAccount中的__index值也是SpecialAccount,s继承自SpecialAccount,而SpecialAccount又继承自Account,Lua在s中找不到deposit字段时,会查找SpecialAccount,如果仍找不到deposit字段,就会查找Account,最终会在那里找到deposit字段。
SpecialAccount重新定义了基类继承的方法,如SpecialAccount中的withdraw函数,当调用s:withdraw(200)时,Lua就不会再Account中查找了,因为Lua会在SpecialAccount中找到withdraw方法。
补充说明:
Lua中对象有一个特殊现象,无需为指定一种新行为而创建一个新类,如果只有一个对象需要这种特殊的行为,那么可以直接在该对象中实现这个行为,例如,账户s表示一个特殊的客户,这个客户的透支额度总是余额的10%。那么可以这么修改这个对象:
在这段代码后,调用s:withdraw(200)还是会执行SpecialAccount中的withdraw函数,但是withdraw调用的self:getLimit则是上面的定义。
完整代码:
模块结构:
init.lua
MAccount=require("class.account")
MSpecialAccount=require("class.specialAccount")
local LoggerConsole=require("logging.console")
Logger=LoggerConsole()
main.lua
local path="C:\\Users\\Administrator\\Desktop 2\\Thinking\\Lua\\"
package.path=string.format("%s;%s?.lua;%s?/init.lua",package.path,path,path) require("class") local function main()
local account=MAccount.Account:new()
account:deposit(500)
account:withdraw(125)
print(account) account=MSpecialAccount.SpecialAccount:new()
print(account:getLimit())
account:deposit(300)
account:withdraw(1200)
print(account)
end main()
说明:
上述修改了package.path 的路径,具体原因参考 本博客“【Lua】模块和包”文章
【Lua】面向对象编程(一)的更多相关文章
- Lua面向对象编程
		Lua中的table就是一种对象,看以下一段简单的代码: , b = } , b = } local tb3 = tb1 if tb1 == tb2 then print("tb1 == t ... 
- lua面向对象编程 《lua程序设计》 16章 笔记
		Lua中的table就是一种对象,即它拥有状态.拥有独立于其值的标识(self).table与对象一样具有独立于创建者和创建地的征集周期 什么叫对象拥有独立的生命周期? Account = {bala ... 
- lua 面向对象编程类机制实现
		lua no class It is a prototype based language. 在此语言中没有class关键字来创建类. 现代ES6, 已经添加class类. prototype bas ... 
- Lua 之面向对象编程
		Lua 之面向对象编程 Lua并不是为面向对象而设计的一种语言,因此,仅从原生态语法上并不直接支持面向对象编程,但Lua的设计中仍然包含了很多面向对象的思想,理解它们也更有助于理解Lua自身的一些高级 ... 
- 【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法
		版权声明:本文为博主原创文章,转载请注明出处. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. 早期的计算机编程是基于面向过程的方法,通过设计一个算法就可以解决当时 ... 
- lua面向对象封装及元表(metatable)性能测试
		Lua本身是没有面向对象支持的,但面向对象编程在逻辑复杂的大型工程却很有用.于是很多人用Lua本身的数据结构table来模拟面向对象.最简单的一种方法是把对象的方法.成员都放到table中.如: -- ... 
- 云风:我所偏爱的C语言面向对象编程范式
		面向对象编程不是银弹.大部分场合,我对面向对象的使用非常谨慎,能不用则不用.相关的讨论就不展开了. 但是,某些场合下,采用面向对象的确是比较好的方案.比如 UI 框架,又比如 3d 渲染引擎中的场景管 ... 
- cocos2d-x-lua基础系列教程三(lua面向对象)
		lua 类 Lua 事实上不是面向对象语言 我们能够用table 模拟仿照面向对象编程 lua 中的this 类似的是self table 也具有生命周期 2,使用table 创建类 projed ... 
- 一步步分析:C语言如何面向对象编程
		这是道哥的第009篇原创 一.前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象的编程方式. 虽然C++语言是从C语言发展而来 ... 
- Step By Step(Lua面向对象)
		Step By Step(Lua面向对象) Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: 1 Account = {balance = 0}2 function ... 
随机推荐
- [Scikit-learn] *Dynamic Bayesian Network - Partical Filter
			涉及的一些知识: 机器人的自我定位 Sequential Importance Sampling Ref: http://scipy-cookbook.readthedocs.io/items/Par ... 
- HDU 4497 GCD and LCM  (分解质因数)
			链接 :  http://acm.hdu.edu.cn/showproblem.php?pid=4497 假设G不是L的约数 就不可能找到三个数. L的全部素因子一定包括G的全部素因子 而且次方数 ... 
- 面向对象----构造方法、this 关键字、函数的参数传递、package语句/import语句
			构造方法 构造器的定义.作用 构造方法的特征 它具有与类相同的名称:它不含返回值: 注意:在构造方法里不含返回值的概念是不同于“void”的,在定义构造方法时加了“void”,结果这个方法就不再被自动 ... 
- 第一篇:《UNIX 网络编程 第二版》编译环境的搭建
			第一步:搭建基本的编译环境 安装gcc, g++, bulid-essential等编译软件 第二步:下载本书示例源码包 第三步:解压下载到的包并放在用户主目录中 第四步:进入包内并执行以下命令 su ... 
- HTML 解析
			xml,json都有大量的库来解析,我们如何解析html呢? TFHpple是一个小型的封装,可以用来解析html,它是对libxml的封装,语法是xpath.今天我看到一个直接用libxml来解析h ... 
- 使用vim-pathogen 进行插件管理
			使用vim的插件管理器 pathogen进行vim的插件管理. 1. pathogen 管理插件 pathogen让每个插件占有一个单独的目录,解决了文件分散的问题.安装完 pathogen之后,只需 ... 
- web基础---->okhttp的使用
			今天我们就讲一下okhttp的使用,具体的okhttp使用可以参见官方的文档. okhttp的使用 一.okhttp的下载安装 Download the latest JAR or grab via ... 
- MQTT协议笔记之头部信息
			前言 记忆不太好的时候,只能翻看以前的文章/笔记重新温习一遍,但找不到MQTT协议有关订阅部分的描述,好不容易从Evernote中找到贴出来,这样整个MQTT协议笔记,就比较齐全了. SUBSCRIB ... 
- LeetCode——Search Insert Position
			Description: Given a sorted array and a target value, return the index if the target is found. If no ... 
- Elasticsearch配置参数介绍
			Elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml.第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来 ... 
 
			
		

