Lua 面向对象

本文介绍了Lua中的面向对象编程,包括类的概念、self字段的使用、类的实例化、继承、为实例添加额外方法以及多重继承。Lua通过基于原型的方式实现对象组织,利用元表和self实现类的功能。文章还探讨了Lua中实现私有性的方式,并提供了示例代码帮助理解。
摘要由CSDN通过智能技术生成

一、前言

Lua 中一张表 table 就是一个对象(注意不是类,是对象)。他具有以下的特性:

  1. 表和对象都可以拥有状态
  2. 表和对象都拥有一个与其值无关的标识(self)
  3. 两个具有相同值的对象是两个不同的对象,而一个对象可以具有多个不同的值
  4. 表和对象一样,具有与创建者和被创建者位置无关的生命周期

二、类

1、 Lua 的类

Lua 并没有类这一概念,而是通过 “基于原型” 的方式进行组织,而原型其实也是一个实例对象。

换而言之,我们通过元表的方式,让 Lua 的实例对象在找不到对应的属性或方法时,从其元表的 __index 属性指定的表(即上面所说的原型,其实他也是实例对象)或方法中获取,而如果这里指定的表也没有对应的属性,则继续往该表(也就是原型)的元表继续查找,直到查找到或全部查找完还没有找到对应的属性或方法为止。

2、self 字段

在类中,this(在 Lua 中是 self) 很重要,因为他可以让不同实例调用同一方法不会有互相干扰

举个例子

下面的例子中,withdraw 方法内部固定写了 Account ,所以只要将 Account 删除,则会有异常

local Account = {
    balance = 0 }
function Account.withdraw(v)
    Account.balance = Account.balance - v
end

Account.withdraw(100)
print(Account.balance)              --> -100

local a, Account = Account, nil
a.withdraw(100)                     --> 这里会报错,因为 withdraw 内部使用了 Account ,而这个值已经被移除

所以这里如果有一个可以指向自身的指针就可以避免这一问题,则将 function Account.withdraw(v) 方法多加一个 self 参数,来决定函数内部的操作是针对哪个实例,变成为 function Account.withdraw(self, v) ,改变后的代码:

local Account = {
    balance = 0 }
function Account.withdraw(self, v)
    self.balance = self.balance - v
end

local a = Account
Account = nil
a.withdraw(a, 100)
print(a.balance)

但是这样的使用就会麻烦一些,每次使用都需要将自己传入,Lua 有一个语法糖,如果第一个参数是指向自身,则可以使用冒号(:)进行调用。

同时也可以使用冒号(:)进行定义方法,这样会自动在参数的最前面添加一个 self 的参数,方法内部就可以进行使用了,具体代码如下:

冒号定义的方法,也可以使用点方式调用,只是需要传入多一个参数指向自己

local Account = {
    balance = 0 }
-- 使用 : 就相当于 function Account.withdraw(self, v)
function Account:withdraw(v)
    self.balance = self.balance - v
end

local a &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值