lua的类也是一个table,它有自己的metatable,主要有__index元操作,有成员函数,有构造函数,设计这样一个函数,它构造出这样一个table。
function Class(t)
local class = {};
class.__member_data = t or {};
class.__index = class;
function class:InheritMemberData(...)
local base = {self, ...};
local member_data = {};
for _, t in pairs(base) do
for k, v in pairs(t.__member_data) do
if member_data[k] then
print("redefined member data '" .. k .. "'");
else
member_data[k] = v;
end
end
end
self.__member_data = member_data;
end;
function class:InheritInterface(...)
local base = {self, ...};
if select("#", ...) == 1 then
setmetatable(self, ...);
else
self.__index = function(_, key)
for k, v in pairs(base) do
local value = v[key];
if value then
return value;
end
end
end;
end
end;
function class:Inherit(...)
self:InheritMemberData(...);
self:InheritInterface(...);
return self;
end;
function class:New(o)
local obj = {};
for k, v in pairs(self.__member_data) do
obj[k] = v;
end
for k, v in pairs(o or {}) do
if obj[k] then
obj[k] = v;
end
end
setmetatable(obj, self);
return obj;
end;
return class;
end
使用的时候就像下面这样:
B1 = Class {
x = 0; -- 成员定义和默认值
};
function B1:GetX() -- 成员函数定义
return self.x;
end
B2 = Class {
y = 0;
};
function B2:GetY()
return self.y;
end
D = Class {
z = 0;
}:Inherit(B1, B2); -- 继承自B1和B2,继承所有的成员数据和成员函数
function D:GetZ()
return self.z;
end
local d = D:New{x = 1, y = 2, z = 3};
print(d:GetX(), d:GetY(), d:GetZ());
这种继承,是有多态的性质的,如果在子类中找不到某个名字,才会去基类中找,如果子类中有override的接口,则会调用子类的。最后还差一个权限控制,也就是隐藏信息,下回设计。