【Lua】面向对象

Lua使用table来面向对象。


一个简单的 Account 类:

Account = {balance = 0}

function Account.sub(self, v)                       
	self.balance = self.balance - v
end

a = Account
a.sub(a, 10)                                    
print(a.balance)

这里还有一种更简介表示方法:

Account = {balance = 0}

function Account:sub(v)                       --使用冒号
	self.balance = self.balance - v
end

a = Account
a:sub(10)                                    --使用冒号
print(a.balance)

这里的冒号是Lua的一种语法糖。



local Account = {}

--[=[
Account = {
	value,
}
--]=]

function Account:new(account)
	account = account or {}
	setmetatable(account, self)
	self.__index = self
	return account
end

function Account:display()
	print(self.value)
end

local account = Account:new({value = 10})		
account:display()					--相当于Account.display(account)

这里通过 Account:new 得到的 account 的元表为 Account,且具有 __index  = Account。这样当 account:display() 时,虽然 account 并没有 display() 函数,但会调用其元表的 __index 字段里的 display() 函数。这里如果将

setmetatable(account, self)
self.__index = self

换成

setmetatable(account, {__index = self})

同样可以达到目的。


实例对象account中并没有display方法,而是继承自Account的方法,而且传入display方法中的self却是account。这样就可以让Account(这个“类”)定义操作。除了方法,account还能从Account继承所有的字段。如下:

local Account = {value = 20}

--[=[
Account = {
	value,
}
--]=]

function Account:new(account)
	account = account or {}
	setmetatable(account, self)
	self.__index = self
	return account
end

function Account:display()
	self.value = self.value + 100
	print(self.value)
end

local account = Account:new{}		
account:display()								
account:display()								
print(Account.value)

输出结果为:

120
220
20

account 第一次调用 display() 时,等号左边的 self.value 就是 account.value,而右边的 self.value 则使用了 Account.value。第二次调用时 account.value 字段已有。




继承

上面的例子其实已经有了继承,account 继承自 Account。这里我们在进一步介绍下:

local Person = {sex = "male"}

function Person:new(person)
	person = person or {}
	setmetatable(person, self)
	self.__index = self 
	return person
end

function Person:display()
	print(self.sex)
end

local Son = Person:new{}		
Son:display()

local Grand = Son:new{sex = "female"}
Grand:display()


这个例子中,Son 继承自 Person,之后 Grand 继承自 Son。当执行Grand:display() 时,Lua在Grand中找不到display字段,就会查找Son;如果仍然找不到display字段,就查找Person,最终会在Person中找到display字段。可以这样想一下,如果在Grand中存在了display字段,那么就不会去Person中再找了。所以,我们就可以在Grand中重定义display字段,从而实现特殊版本的display函数。继承的实现依靠了元表 __index 字段的逐层指向。Son 元表的 __index 指向 Person, Grand 元表的 __index 指向 Son。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值