Metatable与面向对象继承

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Metatable与面向对象继承相关的知识,希望对你有一定的参考价值。

Lua是个面向过程的语言, 但通过Metatable可以模拟出面向对象的样子. 其关键就在于__index这个域. 他提供了表的索引值入口. 这很像重写C#中的索引器, 当表要索引一个值时如table[key], Lua会首先在table本身中查找key的值, 如果没有并且这个table存在一个带有__index属性的Metatable, 则Lua会按照__index所定义的函数逻辑查找. 仔细想想, 这不正为面向对象中的核心思想继承, 提供了实现方式么. Lua中实现面向对象的方式非常多, 但无论哪种都离不开__index.


local bb = {cancry = true} 

function bb:new()
    b = {}
    self.__index  = self--改变自己的索引值入口
    setmetatable(b, self)--将b的索引值入口设成self,即(local bb = {cancry = true})
    return b
end

local ostrich = bb:new()
print(ostrich.cancry)



另外一个教程:


Person={}
  
 function Person:new(p)
     local obj = p
     if (obj == nil) then
         obj = {name="ChenHao", age=37, handsome=true}
     end
     self.__index = self--是怕self被扩展后改写,所以,让其保持原样
     return setmetatable(obj, self)--返回第一个参数
 end
  
function Person:toString()
     return self.name .." : ".. self.age .." : ".. (self.handsome and "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‘s fucking", age=70, handsome=false}
 print(kf:toString())



继承:


Student = Person:new()
  
 function Student:new()
     newObj = {year = 2013}
     self.__index = self
     return setmetatable(newObj, self)
 end
  
 function Student:toString()
     return "Student : ".. self.year.." : " .. self.name
 end


student = Student:new()
print(student:toString())


本文出自 “陪你度过漫长岁月” 博客,请务必保留此出处http://4774721.blog.51cto.com/4764721/1792277

以上是关于Metatable与面向对象继承的主要内容,如果未能解决你的问题,请参考以下文章

lua面向对象封装及元表(metatable)性能测试

『游戏开发』在Lua中实现面向对象特征--模拟类继承多态

游戏开发在Lua中实现面向对象特性——模拟类继承多态

Lua面向对象编程

Lua面向对象编程

Lua-面向对象中类的构造