类和对象:

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】面向对象编程(一)的更多相关文章

  1. Lua面向对象编程

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

  2. lua面向对象编程 《lua程序设计》 16章 笔记

    Lua中的table就是一种对象,即它拥有状态.拥有独立于其值的标识(self).table与对象一样具有独立于创建者和创建地的征集周期 什么叫对象拥有独立的生命周期? Account = {bala ...

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

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

  4. Lua 之面向对象编程

    Lua 之面向对象编程 Lua并不是为面向对象而设计的一种语言,因此,仅从原生态语法上并不直接支持面向对象编程,但Lua的设计中仍然包含了很多面向对象的思想,理解它们也更有助于理解Lua自身的一些高级 ...

  5. 【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法

    版权声明:本文为博主原创文章,转载请注明出处. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. 早期的计算机编程是基于面向过程的方法,通过设计一个算法就可以解决当时 ...

  6. lua面向对象封装及元表(metatable)性能测试

    Lua本身是没有面向对象支持的,但面向对象编程在逻辑复杂的大型工程却很有用.于是很多人用Lua本身的数据结构table来模拟面向对象.最简单的一种方法是把对象的方法.成员都放到table中.如: -- ...

  7. 云风:我所偏爱的C语言面向对象编程范式

    面向对象编程不是银弹.大部分场合,我对面向对象的使用非常谨慎,能不用则不用.相关的讨论就不展开了. 但是,某些场合下,采用面向对象的确是比较好的方案.比如 UI 框架,又比如 3d 渲染引擎中的场景管 ...

  8. cocos2d-x-lua基础系列教程三(lua面向对象)

    lua 类 Lua 事实上不是面向对象语言 我们能够用table 模拟仿照面向对象编程 lua 中的this 类似的是self  table 也具有生命周期 2,使用table  创建类 projed ...

  9. 一步步分析:C语言如何面向对象编程

    这是道哥的第009篇原创 一.前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象的编程方式. 虽然C++语言是从C语言发展而来 ...

  10. Step By Step(Lua面向对象)

    Step By Step(Lua面向对象) Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: 1 Account = {balance = 0}2 function ...

随机推荐

  1. Oracle收购Apiary来加强其API集成云

        Oracle宣布计划于1月19日收购Apiary,一家专注于API设计和协作的API管理公司.Apiary最为人所知的是API flow,其API管理平台.     Oracle并没有宣布计划 ...

  2. 在php代码中调用帝国cms头部变量temp.header的方法

    在php代码中调用帝国cms头部变量temp.header的方法 代码如下: <?php require("../e/class/connect.php"); if(!def ...

  3. c++ 类数据成员的定义、声明

    C++为类中提供类成员的初始化列表类对象的构造顺序是这样的:1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员2.进入构造函数后在构造函数中执行一般计算  1.类里面的任何成员变量在定义时是不 ...

  4. DoBox 下载

    DoBox下载 一款简单十分好用的办公助手,用于记录您接下来需要做的事情.待办事项小工具 - DoBox DoBox下载 下载地址:http://www.wxzzz.com/?id=141 最新版本: ...

  5. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第四节:3D公告板

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第四节:3D公告板 视频地址:http://edu.csdn.net/course/attend/1330/20804 交流论坛:mo ...

  6. 使用python调用zxing库生成二维码图片

    (1)     安装Jpype 用python调用jar包须要安装jpype扩展,在Ubuntu上能够直接使用apt-get安装jpype扩展 $ sudo apt-get install pytho ...

  7. Java精选笔记_IO流(字节流、InputStream、OutputStream、字节文件、缓冲区输入输出流)

    字节流 操作图片数据就要用到字节流. 字符流使用的是字符数组char[],字节流使用的是字节数组byte[]. 字节流读写文件 针对文件的读写,JDK专门提供了两个类,分别是FileInputStre ...

  8. docker中文、手册、教程

    Docker资源 Docker官方英文资源: docker官网:http://www.docker.com Docker windows入门:https://docs.docker.com/windo ...

  9. IIC协议

    总线信号 :  SDA :串行数据线 SCL  :串行时钟 总线空闲状态 : SDA :高电平 SCL :高电平 起始位:SCL为高电平期间    SDA出现下降沿 终止位:SCL为高电平期间 SDA ...

  10. CMS3.0——初次邂逅express

    前言: 刚接手cms3.0的工作,似乎对一切都那么的不熟悉,于是在开始新需求之前,先做一个简单的登录系统. 项目目录: 1.使用webstroms建expreess项目,非常方便简单,建好的项目目录就 ...