最近学习lua,有几个要点需要总结一下
最重要的莫过于使用lua来实现面相对象了
由于lua中的对象其实是一个table,而metatable为table的原表,为访问一个table提供了可扩展的可能性,因此使用metatable来扩展table的功能进而实现对象和继承的功能.
当访问一个table的某个变量的时候如果该table中不存在就会去该metatable的__index 里面去找,该__index 可为一个table 也可以为一个方法,
1 当为方法的时候需要传入一个table和一个索引的key
2 为一个table时候来通过赋值给自身来实现可以访问该metatale的所有方法属性的功能,而lua的面相对象就是通过该途径实现的。以下面的例子来说明
Rectangle = {area = 2,length = 3,breadth = 4} --设置一个table叫Rectangle
--派生类方法 new
function Rectangle:new (o,length,breadth)
o = o or {}
setmetatable(o, self) --设置 o的metatable为Rectangle table(注意全程 ractangle 全程是只有一个的)
self.__index = self --把搜寻o的某一个变量变为搜寻 Rectangle 的变量
self.length = length or 0
self.breadth = breadth or 0
self.area = length * breadth;
return o
end
function Rectangle:printArea()
print("矩形面积为 ",self.area)
end
上面的例子先是创建了一个table叫Rectangle 里面有几个属性叫 area,length breadth.
通过一个new方法返回了一个新创建的table实际上这个new方法只是修改了原Rectangle的值,但是由于Rectangle为这个新table的metatable因此访问它的变量方法跟访问在new 方法中重新赋值的Rectangle 一样.
Square = Rectangle:new(nil,30,9)
--square 派生方法
function Square:new(o,breadth)
o = o or Rectangle:new(o,2,3,4) -- 后面的参数不能省略否则访问的时候就会为空
setmetatable(o,self)
self.__index = self
self.breadth = breadth or 0
return o
end
-- 派生类方法 printArea
function Square:printArea ()
print("正方形面积为 ",self.area)
end
上面的代码创建了一个继承Rectangle的对象 Square,改对象实际也是一个table,也是通过一个new方法来返回改对象
把改对象的metatable设置了成了Rectangle 因此访问该对象跟访问在new方法中重新赋值后的Rectangle对象一样。
综上所述:在lua中创建对象和继承对象,实际上都是跟访问某一个table一样,只不过在创建对象时候访问的改table修改后的table,访问继承对象是访问的是经过上一步创建对象修改的后的table之后再次修改后的table.