【Lua基础系列】之面向对象编程--类的实现与继承
大家好,我是Lampard~~
欢迎来到Lua基础系列的博客
PS:本博客知识参考资料为:《Lua程序设计第四版》,该书由Lua的创始人2018年所编著,所以大家可以放心去吸收知识
前文再续,书接上一回。
今天要接着讲Lua中的面向对象编程中的类的实现与继承。
(一) 定义一个类:
类在面向对象语言中就好象一个模板,通过模板所创建的实例就具有模板中规定的特性。Lua中没有类的概念,每一个对象规定自己的行为,每一个对象就是自己的实例。不过在Lua中模拟“类”并不难,我们可以用继承的概念,使用两个对象,让其中一个对象作为另一个对象的“类”。
在Lua语言中,我们如果有两个对象A和B,要让B成为A的一个原型,只需要:
B.__index = B // 把B表的__index字段仍然设置为B
setmetatable(A,B) // 把B表设置为A表的原表
这时候我就出现了疑惑:既然说把B设置为A的原表,那A没有的属性就可以在B中寻找了呀,设置B.__index是什么东西?
而这个理解是完全错误的,实际上,即使将A的元表设置为B,而且B中也确实有这个成员,返回结果仍然会是nil,原因就是B的__index元方法没有赋值。拥有了元表等于告诉了Lua:在A表找不到数据时,我们有解决方法;而元表中的__index则是告诉Lua:你从我的__index中找去吧。
举个例子:
这个时候son想访问父亲的house变量还是返回一个nil的,所以为了实现功能,我们应该这样改:
OK,这个时候我们就可以实现以B类作为原型的A类对象的实现啦
可是这又是setmetatable又是要设置__index,弄得很不美观,我们是用java,C++的时候不就是new来new去的吗?
所以我们就可以把它用一个new封装起来:
(二) 继承:
把B当做父类,并且在A中增加或修改新增的函数罢了。当我们使用函数时,Lua会先在A(子类)中寻找,遇到重名或者仅在A中存在的函数,会优先调用。若查不到才会走元表,从父类中寻找这一流程。
举个例子:
Account = { balance = 0 }
-- 余额为0的账户
function Account:withdraw( v )
if self.balance > v then
self.balance = self.balance - v
else print("balance is not enough!")
end
end
-- 取款
function Account:new(o)
o = o or {}
setmetatable(o,self)
self.__index = self
return o
end
普通的银行账户不允许透支取款,那么如果我们定义一个信用卡账户继承它,并且获得透支额度则可以这样做: