【Lua】面向对象

来源:互联网 发布:js实现点击重置按钮 编辑:程序博客网 时间:2024/06/16 05:49

Lua使用table来面向对象。


一个简单的 Account 类:

Account = {balance = 0}function Account.sub(self, v)                       self.balance = self.balance - venda = Accounta.sub(a, 10)                                    print(a.balance)

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

Account = {balance = 0}function Account:sub(v)                       --使用冒号self.balance = self.balance - venda = Accounta:sub(10)                                    --使用冒号print(a.balance)

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



local Account = {}--[=[Account = {value,}--]=]function Account:new(account)account = account or {}setmetatable(account, self)self.__index = selfreturn accountendfunction Account:display()print(self.value)endlocal 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 = selfreturn accountendfunction Account:display()self.value = self.value + 100print(self.value)endlocal account = Account:new{}account:display()account:display()print(Account.value)

输出结果为:

12022020

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 personendfunction Person:display()print(self.sex)endlocal 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。


原创粉丝点击