热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Lua学习笔记:面向对象

Lua学习笔记:面向对象https:blog.csdn.netliutianshx2012articledetails41921077Lua中只存在表(Table)这么唯一一种数据
Lua学习笔记:面向对象

https://blog.csdn.net/liutianshx2012/article/details/41921077


Lua 中只存在表(Table)这么唯一一种数据结构,但依旧可以玩出面向对象的概念。

添加成员函数

好吧,如果熟悉 C++ 还是很好理解类似的进化过程的:如果说 struct 里可以添加函数是从C 过渡到 C++ 的第一认识的话,为 Table 添加函数也可以算是认识 Lua 是如何面向对象的第一步吧。


     

    player = { health = 200 } --> 一个普通的 player 表,这里看作是一个对象

     

    function takeDamage(self, amount)

     

    self.health = self.health - amount

     

    end

     

     

     

    takeDamage(player, 20) --> 调用

如何将独立的 takeDamage 塞进 player 中咧?答案是直接定义进去:


     

    player = { health = 200 }

     

    function player.takeDamage(self, amount)

     

    self.health = self.health - amount

     

    end

     

     

     

    player.takeDamage(player, 20) --> 调用

这样就相当于在 player 表中添加了一个叫做 takeDamage 的字段,和下面的代码是一样的:


     

    player = {

     

    health = 200,

     

    takeDamage = function(self, amount) --> Lua 中的函数是 first-class value

     

    self.health = self.health - amount

     

    end

     

    }

     

     

     

    player.takeDamage(player, 20) --> 调用

调用时的 player.takeDamage(player,20) 稍显不和谐(据说用术语叫做 DRY),于是就要出动「冒号操作符」这个专门为此而生的语法糖了:


     

    player:takeDamage(20) --> 等同于 player.takeDamage(player, 20)

     

    function player:takeDamage(amount) --> 等同于 function player.takeDamage(self, amount)


从对象升华到类

类的意义在于提取一类对象的共同点从而实现量产(我瞎扯的 >_<)。同样木有 Class 概念的 Javascript使用 prototype 实现面向对象,Lua则通过 Metatable 实现与 prototype 类似的功能。


     

    Player = {}

     

     

     

    function Player:create(o) --> 参数 o 可以暂时不管

     

    o = o or { health = 200 } --> Lua 的 or 与一般的 || 不同,如果非 nil 则返回该非 nil 值

     

    setmetatable(o, self)

     

    self.__index = self

     

    return o

     

    end

     

     

     

    function Player:takeDamage(amount)

     

    self.health = self.health - amount

     

    end

     

     

     

    playerA = Player:create() --> 参数 o 为 nil

     

    playerB = Player:create()

     

     

     

    playerA:takeDamage(20)

     

    playerB:takeDamage(40)

     

     

顾名思义 Metatable 也是一个 Table,可以通过在其中存放一些函数(称作metamethod)从而修改一些默认的求值行为(如何显示为字符串、如何相加、如何连接、如何进行索引)。Metatable的 __index 域设置了「如何进行索引」的方法。例如调用foo.bar 时,如果在 foo 中没有找到名为 bar 的域时,则会调用Metatable:__index(foo,bar)。于是:

playerA:takeDamage(20)


因为在 playerA 中并不存在 takeDamge 函数,于是求助于Metatable:

getmetatable(playerA).__index.takeDamage(playerA, 20)


带入 Metatable 后:

Player.__index.takeDamage(playerA, 20)


因为 Player 的 __index 在 create 时被指定为 self,所以最终变为:

Player.takeDamage(playerA, 20)


于是 takeDamage 的 self 得到了正确的对象 playerA


继承

继承是面向对象的一大特性,明白了如何创建「类」,那么继承也就比较明了了,还记得大明湖畔的参数 o 么?


     

    RMBPlayer = Player:create()

     

    function RMBPlayer:broadcast(message) --> 为子类添加新的方法

     

    print(message)

     

    end

     

    function RMBPlayer:takeDamage(amount) --> 子类重载父类方法

     

    self.health = self.health - amount / (self.money / 100)

     

    end

     

     

     

    vip = RMBPlayer:create { mOney= 200 } --> 子类添加新成员(单个 Table 作为参数可以省略括号)

     

     

     

    vip:takeDamage(20)

     

    vip:broadcast("F*ck")

以上便是 Lua 中实现面向对象的基本方法。

========================================


Lua学习笔记:面向对象的相关教程结束。



推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了go接口相关的知识,希望对你有一定的参考价值。一、接口是什么接口提供了一种方式来 说明 对象的行为 ... [详细]
  • const限定符全解一、const修饰普通变量  intconsta500;  constinta600;  上述两种情况相同,都是声明一个const型的变量,它们 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
author-avatar
qiutuiq
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有