前言
在lua里是没有类的概念的,但是可以利用表(table)和元表特性来实现面向对象和继承。lua的表类似于一个对象,每个对象都有自己的方法和属性。当访问一个表中不存在的属性时,系统不会直接返回错误,而是访问该表的元表中的 __index 元方法。 __index 元方法既可以是一个方法,也可以是一张表,当 __index 为表时,从 __index 指示的表中查询不存在的属性,当 __index 为方法时,访问不存在的属性会触发调用此方法。
示例
利用这一特性,继承可以如下来实现:
local base = {x=10,y=20,z=100}
function base:new(o)
o = o or {}
self.__index = self
setmetatable(o,self)
return o
end
function base:show()
print("base: " .. self.x .. " " .. self.y)
end
上例代码中 base 为"基类",方法 new 完成的功能是以调用者为"基类",以 o 为初始表,创建一个新对象,共有两个参数(方法名中使用":“是lua的一种语法,默认第一个参数为调用者自身),一个为调用者自身,即 “self”(类似于c++中的this指针),另一个参数 o 为初始表。
self.__index = self将调用者的 __index 元方法设置为调用者自身;setmetatable(o,self)将 o 的元表设置为调用者,如此在返回的新对象(即 o)中访问不存在的属性就会触发在"基类”(即 base)中查找;
接上,继承示例如下:
local test = base:new({z=0,f=99})
-- test中不存在,base中存在
print(test.x) -- ====>> 10
print(test.y) -- ====>> 20
test:show() -- ====>> base: 10 20
-- test中不存在,base中不存在
print(test.a) -- ====>> nil
-- test中存在,base中也存在(会被覆盖)
print(test.z) -- ====>> 0
上例中 test 继承自 base,访问 test 中没有的属性,会到 base 中继续查找。继续来看下面的例子。
local temp = test:new({})
-- temp中不存在,base中存在
print(temp.x) -- ====>> 10
-- temp中不存在,test中存在
print(temp.z) -- ====>> 0
print(temp.f) -- ====>> 99
上例中 temp 是从 test 中继承而来的,test 又是从 base 继承来的,所以 temp 可以访问到 test 和 base 中的所有属性,需要注意的是"父类"中同名的属性或方法会被"子类"覆盖。
604

被折叠的 条评论
为什么被折叠?



