最近在学习lua语言的时候,对面向对象这个内容有点疑惑,开个坑解释一下。
首先先学习一些元表的概念,菜鸟教程传送https://www.runoob.com/lua/lua-metatables.html
这里要解释一下元表中的__index,对元表的__index设置了值后,对表的数据进行访问,如果
表中没有这项数据,那么就会去查找元表中的__index字段,那么__index字段如果也是一张表,
那么就再去查找__index指向的表。‘
到这一步你就会想了,如果把__index指向的表设置为元表自身会怎么样?
那么当表中查找不到数据的时候,就会去元表中查找数据。(是不是很像继承?)
看看下面的代码:
Base = {key} Base.__index = Base function Base:new(key) this = setmetatable({},Base) this.key = key return this end a = Base:new(10) b = Base:new(20) print(a.key)--10 print(b.key)--20
这里要解释一下Base:new中的:的意思,一般来说我们对Base模块添加函数是直接Base.new就行,
如果设置成Base:new,那么就会默认传递一个字段self,self可以对元表进行操作,如果是成员函数,
self会对调用的对象进行操作。
我们可以看到,有了这样一个new函数后,每当我们调用后,就会产生一个新的表,并且把表的元表设置为Base,
然后初始化字段,最后返回。我们可以看到两个对象a,b的key值是不一样的。说明了a,b这两个表示分别存储key
这个字段的,而元表中的key也是单独存储的。这样其实我们就已经完成了从元表产生对象这一过程。
那么如何进行继承操作呢?关键点在于,Base创建新对象是从空表创建的{},而派生类Derived是从Base类创建。
Base = {key} Base.__index = Base function Base:new(key) this = setmetatable({},Base) this.key = key return this end function Base:display() print(self.key) end Derived = Base:new() Derived.newkey = nil Derived.__index = Derived function Derived:new(key,newkey) this = setmetatable(Base:new(key),Derived) this.newkey = newkey return this end function Derived:display() print(self.key,self.newkey) end a = Base:new(10) b = Base:new(20) a:display()--10 b:display()--20 c = Derived:new(10,20) d = Derived:new(20,30) c:display()--10 20 d:display()--20 30
如何去理解呢?其实就是元表和产生的表其实数据字段都是各自的,函数可以理解为共用的,
在基类中保存一份,通过元类的__index字段去访问。