您的位置:首页 > 编程语言 > Lua

Lua五:类与继承的实现

2021-10-04 16:20 706 查看

Lua中没有类,即没有在对象生成中有模子的概念,但是有原型的概念。基于原型的语言(prototype-based language)中,每个对象可以有一个原型(prototype)。原型也是一种普通的对象,当对象(类的实例)遇到一个未知操作时会首先在原型中查找。类和原型都是一种组织多个对象间共享行为的方式。

创建原型的方法如setmetatable(A, {__index = B}),即把B作为A的原型。下面的代码是简单表达账户存取和提取的操作:

Account = { balance=0}

function Account : withdraw ( v)

self.balance = self.balance – v

end

function Account : deposit (v)

self.balance = self.balance + v

end

现在,需要实现类的概念,即Account作为类,下列代码中定义的a作为其对象。

local mt = {__index = Account}

function Account. new (o)      --该函数用于新建账户,即创建对象

o = o or {f}       --如果用户没有提供则创建一个新的表

setmetatable(o,mt )    --将mt作为新创建的对象的元表,而元表中的__index为Account类

return o

end

a = Account . new{ balance = 0}

a : deposit ( 100.00 )   --相当于  getmetatable(a).__index . deposit(a,100.00)

对于上述代码,我们可以进行一些改进。方法new会变成:

function Account : new ( o)

o = o or {}

self. __index = self

setmetatable(o, self)

return o

end

该改进是,不创建扮演元表角色的新表而是把表Account直接用作元表。第同时对new方法也使用冒号语法。加入了这两个改动后,现在,当我们定义new ()函数时,隐藏的参数self得到的实参是Account,Account._index等于Account,并且 Account被用作新对象的元表。

若想从Account这个类派生一个子类SpecialAccount以允许客户透支,那么可以先创建一个从基类继承了所有操作的空类:

SpecialAccount = Account :new()

直到现在,SpecialAccount还只是基于Account 类创建的一个对象实例。下面:

s = SpecialAccount : new{limit=1000.00}

SpecialAccount就像继承其他方法一样从 Account继承了new,这是由于基于之前的改进,Account被用作新对象的元表。不过,现在执行new时,它的self参数指向的是SpecialAccount。因此,s 的元表会是 SpecialAccount,即s 继承自SpecialAccount,而SpecialAccount又继承自Account。

同时我们可以重新定义子类从基类继承的任意方法,只需要编写一个新方法即可,以修改SpecialAccount从Account类继承的withdraw ()函数为例:

function SpecialAccount : withdraw (v)

if v - self.balance >= self.limit then

error "insufficient funds"

end

self.balance = self.balance – v

end

现在,当调用s:withdraw (200.00)时,因为Lua语言会在SpecialAccount中先找到新的withdraw方法,所以不会再从Account中查找。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: