• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >Lua > Lua中的面向对象编程详解

Lua中的面向对象编程详解

作者: 字体:[增加 减小] 来源:互联网

通过本文主要向大家介绍了lua 面向对象,lua如何实现面向对象,lua面向对象编程,java面向对象详解,面向对象详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

简单说说Lua中的面向对象

Lua中的table就是一种对象,看以下一段简单的代码:
local tb1 = {a = 1, b = 2}
local tb2 = {a = 1, b = 2}
local tb3 = tb1
 
if tb1 == tb2 then
     print("tb1 == tb2")
else
     print("tb1 ~= tb2")
end
 
tb3.a = 3
print(tb1.a)
</div>
上述代码会输出tb1 ~= tb2。说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的。我在《Lua中的模块与包》中也总结了,我们是基于table来实现的模块,在table中可以定义函数,也就是说,每个table对象都可以拥有其自己的操作。看一段代码:
Account = {balance = 0}
function Account.withDraw(v)
     Account.balance = Account.balance - v
end
 
Account.withDraw(10) -- 调用函数
print(Account.balance)
</div>
上面的代码创建了一个新函数,并将该函数存入Account对象的withDraw字段中,然后我们就可以调用该函数了。不过,在函数中使用全局名称Account是一个不好的编程习惯,因为这个函数只能针对特定对象工作,并且,这个特定对象还必须存储在特定的全局变量中。如果改变了对象的名称,withDraw就再也不能工作了。例如以下代码:

a = Account
Account = nil
a.withDraw(100)
</div>
这样就会出现错误。我在这里使用Account创建了一个新的对象a,当将Account赋值为nil时,应该要对a对象不产生任何影响。但是,由于在函数withDraw内部使用了Account,而不是变量a,所以就出现了错误。如果我们将withDraw函数内部的Account.balance = Account.balance – v语句修改为:a.balance = a.balance – v,这样就不会出现错误了。这就表明,当我们需要对一个函数进行操作时,需要指定实际的操作对象,即这里的a,这就需要一个额外的参数来表示该操作者,就好比C++中的this一样,只不过这里将这个关键字换成了self,换完以后的代码如下:

Account = {balance = 0}
function Account.withDraw(self, v)
     self.balance = self.balance - v
end
 
a = Account
Account = nil
a.withDraw(a, 100)
print(a.balance)
</div>
这样再调用,就不会出现错误了。

使用self参数是所有面向对象语言的一个核心。大多数面向对象语言都对程序员隐藏了self参数,从而使得程序员不必显示地声明这个参数。Lua也可以,当我们在定义函数时,使用了冒号,则能隐藏该参数,那么上述代码使用冒号来改下,就是下面这个样子了。

Account = {balance = 0}
function Account:withDraw(v) -- 注意这里的冒号":"
     self.balance = self.balance - v
end
 
a = Account
Account = nil
a:withDraw(100) -- 注意这里的调用时,也需要冒号":"
print(a.balance)
</div>
冒号的作用很简单,就是在方法定义中添加一个额外的隐藏参数,以及在一个方法调用中添加一个额外的实参。冒号只是一种语法便利,并没有引入任何新的东西;如果你愿意,你可以可以不使用self,而是在每次定义一个函数时,手动的加上self,只要你处理好了self,它们都是一样的。

这里乱乱的讲了一些Lua中的东西,主要还是说了table是一个不一样的东西,还有self。接下来,就正式进入面向对象的世界。不要忘了,上面总结的东西是非常有用的。

类

类是什么?一个类就是一个创建对象的模具。例如C++中,每个对象都是某个特定类的实例。在C++中,如果一个类没有进行实例化,那这个类中对应的操作,基本就是一堆“没有用”的代码;而Lua则不一样,即使你不实例化一个“类”,你照样也可以使用“类”名直接调用它的方法(对于C++,请忽视静态的方法);这说明Lua中的“类”的概念与C++这种高级语言中类的概念还是有差别的。在Lua中则没有类的概念,而我们都是通过Lua现有的支持,去模拟类的概念。在Lua中,要表示一个类,只需创建一个专用作其他对象的原型(prototype)。原型也是一种常规的对象,也就是说我们可以直接通过原型去调用对应的方法。当其它对象(类的实例)遇到一个未知操作时,原型会先查找它。

在Lua中实现原型是非常简单的,比如有两个对象a和b,要让b作为a的原型,只需要以下代码就可以完成:
setmetatable(a, {__index = b})  -- 又是元表,不会的请看前几篇关于元表的文章:http://www.jb51.net/article/55812.htm
</div>
设置了这段代码以后,a就会在b中查找所有它没有的操作。若将b称为是对象a的“类”,就仅仅是术语上的变化。现在我就从最简单的开始,要创建一个实例对象,必须要有一个原型,就是所谓的“类”,看以下代码:
local Account = {}  -- 一个原型
</div>

好了,现在有了原型,那如何使用这个原型创建一个“实例”呢?接着看以下代码:

function Account:new(o)  -- 这里是冒号哦
     o = o or {}  -- 如果用户没有提供table,则创建一个
     setmetatable(o, self)
     self.__index = self
     return o
end
</div>
当调用Account:new时,self就相当于Account。接着,我们就可以调用Account:new来创建一个实例了。再看:
local a = Account:new{value = 100} -- 这里使用原型Account创建了一个对象a
a:display()
</div>

上面这段代码是如何工作的呢?首先使用Account:new创建了一个新的实例对象,并将Account作为新的实例对象a的元表。再当我们调用a:display函数时,就相当于a.display(a),冒号就只是一个“语法糖”,只是一种方便的写法。我们创建了一个实例对象a,当调用display时,就会查找a中是否有display字段,没有的话,就去搜索它的元表,所以,最终的调用情况如下:
getmetatable(a).__index(display(a))
</div>

a的元表是Account,Account的__index也是Account。因此,上面的调用也可以使这样的:
Account.display(a)
</div&

您可能想查找下面的文章:

  • 深入解读Lua中迭代器与泛型for的使用
  • Lua中函数与面向对象编程的基础知识整理
  • Lua教程(十三):弱引用table
  • Lua面向对象编程之类的简单实现方式
  • Lua模拟面向对象示例分享
  • Lua中实现面向对象的一种漂亮解决方案
  • Lua中让回调函数支持回调对象方法的解决方法
  • Lua 极简入门指南(七):面向对象编程
  • Lua中的面向对象编程详解

相关文章

  • Redis教程(五):Set数据类型
  • Lua中创建全局变量的小技巧(禁止未预期的全局变量)
  • Lua教程(十二):面向对象编程
  • Lua中的string库和强大的模式匹配学习笔记
  • Lua中的源代码预编译浅析
  • Lua的协程(coroutine)简介
  • linux系统安装Nginx Lua环境
  • Lua编程示例(二):面向对象、metatable对表进行扩展
  • Lua教程(六):编译执行与错误
  • Lua面向对象之多重继承、私密性详解

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Lua中函数与面向对象编程的基础知识整理
    • Lua select函数用法实例
    • Lua中执行系统命令方法介绍
    • Lua学习笔记之函数、变长参数、closure(闭包)、select等
    • Lua中的面向对象编程详解
    • Lua教程(七):数据结构详解
    • 浅析Lua中的迭代器
    • 使用lua实现php的print_r()函数功能
    • Lua table类型学习笔记
    • 在Lua程序中使用SQLite的教程

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有