Metatable与面向对象、继承
Lua是个面向过程的语言, 但通过Metatable可以模拟出面向对象的样子. 其关键就在于__index这个域. 他提供了表的索引值入口. 这很像重写C#中的索引器, 当表要索引一个值时如table[key], Lua会首先在table本身中查找key的值, 如果没有并且这个table存在一个带有__index属性的Metatable, 则Lua会按照__index所定义的函数逻辑查找. 仔细想想, 这不正为面向对象中的核心思想继承, 提供了实现方式么. Lua中实现面向对象的方式非常多, 但无论哪种都离不开__index.
localbb={cancry=true}functionbb:new()b={}self.__index=self--改变自己的索引值入口setmetatable(b,self)--将b的索引值入口设成self,即(localbb={cancry=true})returnbendlocalostrich=bb:new()print(ostrich.cancry)
另外一个教程:
Person={}functionPerson:new(p)localobj=pif(obj==nil)thenobj={name="ChenHao",age=37,handsome=true}endself.__index=self--是怕self被扩展后改写,所以,让其保持原样returnsetmetatable(obj,self)--返回第一个参数endfunctionPerson:toString()returnself.name..":"..self.age..":"..(self.handsomeand"handsome"or"ugly")end
上面我们可以看到有一个new方法和一个toString的方法。其中:
1)self 就是 Person,Person:new(p),相当于Person.new(self, p)
2)new方法的self.__index = self 的意图是怕self被扩展后改写,所以,让其保持原样
3)setmetatable这个函数返回的是第一个参数的值。
于是:我们可以这样调用:
me=Person:new()print(me:toString())kf=Person:new{name="King'sfucking",age=70,handsome=false}print(kf:toString())
继承:
Student=Person:new()functionStudent:new()newObj={year=2013}self.__index=selfreturnsetmetatable(newObj,self)endfunctionStudent:toString()return"Student:"..self.year..":"..self.nameend
student=Student:new()print(student:toString())
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。