十分钟学会Lua五:类与继承的实现
作者:互联网
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中查找。
标签:index,Account,SpecialAccount,学会,Lua,十分钟,new,balance,self 来源: https://www.cnblogs.com/achevery/p/15366598.html