【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 ...
随机推荐
- 如何通过XAMPP来实现单个服务器上建多个网站
xampp 是一个非常方便的本地 apache + php + mysql 的调试环境,在本地安装测试 WordPress 等各种博客.论坛程序非常方便.今天我们来给大家介绍一下,如何使用 XAMPP ...
- 为KindEditor编辑器中的内容添加样式,使得自己定义前台页面显示效果与编辑器效果一致
KindEditor 本身自带有一定的样式,且为内部样式,在使用过程中,难免会发现部分效果不是我们想要的,因此.KindEditor提代了两种方式供使用着调用 1.内部样式.通过 cssData 属性 ...
- Linux 内核中 likely 与 unlikely 的宏定义解析
在 2.6 内核中,随处能够见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么差别? 首先要明白: if(likely(value)) 等价于 if(valu ...
- 超全面的JavaWeb笔记day08<Tomcat&Web应用&HTTP协议>
1.常用软件体系结构 BS:浏览器/服务器 CS:客户端/服务器 WEB资源 动态资源 JSP Servlet 静态资源 html 常用服务器 Tomcat Weblogic Resin JBOSS ...
- cocos2dx游戏--欢欢英雄传说--为敌人添加移动和攻击动作
这里主要为敌人添加了一个移动动作和攻击动作.移动动作是很简略的我动他也动的方式.攻击动作是很简单的我打他也打的方式.效果:代码: #ifndef __Progress__ #define __Prog ...
- Android项目结构介绍
src/存放Java源代码gen/中存放系统自动生成的配置文件Android 4.4.2下包含android.jar文件,这是一个Java归档文件,其中包含构建应用程序所需的所有的Android SD ...
- 我觉得epoll和select最大的区别
最近在用epoll,网速资料很多,大家都说epoll和select的区别比较大,而且select要不停遍历所有的fd,效率要低,而且fd有限制. 但是我认为二者最大的区别在于 先看代码 while ( ...
- Docker源码分析(八):Docker Container网络(下)
1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...
- axios请求本地json
在vux的项目中 1,首先,json文件的位置: 原因: 访问服务器文件,应该把 json文件放在最外层的static文件夹,这个文件夹是vue-cli内置服务器向外暴露的静态文件夹 2,一定要用 ...
- COGS 1224. [SHOI2002]百事世界杯之旅(期望概率)
COGS 1224. [SHOI2002]百事世界杯之旅 ★ 输入文件:pepsi.in 输出文件:pepsi.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] ...


