Lua 极简入门指南(七):面向对象编程

 更新时间:2014年11月03日 09:09:41   投稿:junjie  
这篇文章主要介绍了Lua 极简入门指南(七):面向对象编程,本文讲解了类和继承的概念,并给出了编程实例,需要的朋友可以参考下

在很多面向对象的语言中有类(class)的概念,对象是类的实例。Lua 中不存在类的概念。Lua 就像 JavaScript 一样是面向原型的语言(http://en.wikipedia.org/wiki/Prototype-based_programming),这类语言使用一个对象表示一个“类”,其他对象(此类的实例)使用此对象作为原型。我们有两个 table p 和 obj,将 p 设置为 obj 的原型(回顾:https://www.jb51.net/article/56690.htm):

复制代码 代码如下:

setmetatable(obj, {__index = p})

obj 中不存在的操作会在 p 中查找。

看一个详细的例子:

复制代码 代码如下:

Account = {
    -- 默认的 balance 的值
    balance = 0
}
 
function Account:new(o)
    o = o or {}
    -- 设置原型为 Account
    setmetatable(o, self)
    self.__index = self
    return o
end
 
function Account:deposit(v)
    self.balance = self.balance + v
end
 
function Account:withdraw(v)
    if v > self.balance then
        print('insufficient funds')
        return
    end
    self.balance = self.balance - v
end
 
-- 构建 Account 对象,初始 balance 为 100
local a1 = Account:new{balance = 100}
a1:deposit(100)    --> balance == 200
a1:withdraw(100)   --> balance == 100
 
-- 构建 Account 对象,使用默认的 balance
local a2 = Account:new()
a2:deposit(100)    --> balance == 100

在方法定义时使用冒号能够添加一个隐藏的参数 self 给方法,在方法调用时使用冒号能够将调用者作为一个额外的参数传递给此方法,例如:

复制代码 代码如下:

-- 以下两种写法等价
function Account:deposit(v)
function Account.deposit(self, v)
 
-- 以下两种写法等价
a1:deposit(100)
a1.deposit(a1, 100)

self 为方法的调用者。

在 Account 这个例子中,一个小优化是,我们没有必要创建一个额外的 metatable,而直接使用 Account 作为 metatable。

继承

我们通过一个例子来解释 Lua 如何实现继承。假定我们需要子类 SpecialAccount 继承于 Account,SpecialAccount 是可以透支的。

首先构造一个子类:

复制代码 代码如下:

SpecialAccount = Account:new()

这里 SpecialAccount 拥有了(继承了)Account 的 new 方法。那么我们就可以使用 SpecialAccount 构建对象:
复制代码 代码如下:

local sa = SpecialAccount:new{limit = 1000}
sa:withdraw(100)

这里通过 SpecialAccount:new 构造了对象 sa,并且 sa 的 metatable 为 SpecialAccount。执行 sa:withdraw(100),Lua 在 sa 中找不到 withdraw,就会在 SpecialAccount 中找,在 SpecialAccount 中也找不到 withdraw,然后在 Account 中找到 withdraw 并调用它。Account 中的 withdraw 显然不是我们想要的,我们在 SpecialAccount 中重新定义它:

复制代码 代码如下:

function SpecialAccount:withdraw(v)
    if v - self.balance >= self:getLimit() then
        print('insufficient funds')
        return
    end
    self.balance = self.balance - v
end
 
function SpecialAccount:getLimit()
    return self.limit or 0
end

我们再调用 sa:withdraw(100),Lua 先在 SpecialAccount 中找到 withdraw 并调用它。

相关文章

  • Lua学习笔记之表达式

    Lua学习笔记之表达式

    在Lua中,表达式包括:数值常量、字符串字面值、变量、单目和双目运算符,函数调用,也包括一些非传统的函数定义和表结构。今天我们就来详细了解下lua中的表达式
    2015-04-04
  • Lua中的元方法__newindex详解

    Lua中的元方法__newindex详解

    这篇文章主要介绍了Lua中的元方法__newindex详解,本文讲解了查询与更新、监控赋值、通过table给另一个table赋值等内容,需要的朋友可以参考下
    2014-09-09
  • Lua编程示例(二):面向对象、metatable对表进行扩展

    Lua编程示例(二):面向对象、metatable对表进行扩展

    这篇文章主要介绍了Lua编程示例(二):面向对象、metatable对表进行扩展,本文直接给出实例代码,需要的朋友可以参考下
    2015-07-07
  • 如何使用Vim搭建Lua开发环境详解

    如何使用Vim搭建Lua开发环境详解

    这篇文章主要给大家介绍了关于如何使用Vim搭建Lua开发环境的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • Lua游戏开发教程之时区问题详解

    Lua游戏开发教程之时区问题详解

    时间显示问题说白了就是时差问题,这篇文章主要给大家介绍了关于Lua游戏开发教程之时区问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • Lua中的table浅析

    Lua中的table浅析

    这篇文章主要介绍了Lua中的table浅析,本文讲解了table的构造方法、内置函数unpack等内容,需要的朋友可以参考下
    2014-09-09
  • Lua中执行系统命令方法介绍

    Lua中执行系统命令方法介绍

    这篇文章主要介绍了Lua中执行系统命令方法介绍,Lua中有两种方法可以执行操作系统内置命令,需要的朋友可以参考下
    2015-04-04
  • Lua教程(六):编译执行与错误

    Lua教程(六):编译执行与错误

    这篇文章主要介绍了Lua教程(六):编译执行与错误,本文讲解了、C代码、错误、错误处理与异常、错误消息与追溯等内容,需要的朋友可以参考下
    2015-04-04
  • 利用Lua定制Redis命令的方法详解

    利用Lua定制Redis命令的方法详解

    这篇文章主要给大家介绍了关于利用Lua定制Redis命令的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • Lua 学习笔记之C API 遍历 Table实现代码

    Lua 学习笔记之C API 遍历 Table实现代码

    这篇文章主要介绍了Lua 学习笔记之C API 遍历 Table实现代码,需要的朋友可以参考下
    2014-12-12

最新评论