通过设置Window的__index事件(返回自身pro的table值),在设置.new的时候。为了避免每次创建对象的时候传递self。可以写成
Window.new = function(...)
--setmetatable(o, Window.mt)
--这里可以注册方法
return setmetatable(Window, {__index = _class[Window]})
end
这样每次我们就可以直接使用.new来创建。
在这里实现了对象的实例,但是还未实现继承。
完整的OOP
local _class = {}
class = function(super)
local Window = {}
Window.prototype = {x = 0, y = 0, width = 100, height}
--Window.mt = {}
Window.new = function(...)
--setmetatable(o, Window.mt)
--这里可以注册方法
return setmetatable(Window, {__index = _class[Window]})
end
--Window.mt.__index = function (t, key)
-- return Window.prototype[key]
--end
local vtbl = {}
_class[Window] = vtbl
setmetatable(Window, {__newindex =
function(t,k,v)
vtbl[k] = v
print("enter base")
end
--,
--__index = vtbl,
})
if super then
print("enter super")
setmetatable(vtbl, {__index =
function(t,k)
local ret = _class[super][k]
vtbl[k] = ret
print("enter ")
return ret
end
})
end
return Window
end
要实现继承父类,我们参照c++的编码习惯,为class传递一个参数。通过_class保存每一个基类的信息。每次创建基类的时候通过newindex方法添加基类的成员函数和数据,如果没有相对应newindex不会被调用。 创建子类的时候,通过index把对应基类的信息返回到子类对象。为了实现及时更新,我们应该在创建__newindex方法的时候对虚表进行自身索引,这样子类就可以在它的元方法index里面找到父类的成员函数。 为了在子类创建的对象可以默认调用父类的构造函数的成员数据,我们需要在.new里面加载基类的方法。类似
--Window.mt.__index = function (t, key)
-- return Window.prototype[key]
--end
通过这个元表事件,调用在prototype里面对应key的value。