1.lua 类中其实没有类的概念,一个类只是用一个表(table)来管理的, 如果想要实现子类继承父类,简单来说就是把两个表组到一起。
2.lua中提供了原表(Metatable),可以通过原表来改变原来lua类的一些行为,比如把两个表相加(a+b)
father ={
f = "this is father";
};
father.__index = father; // 必须加上这一步 解释看下文
child = {
c = "this is child";
};
print(child.c)
print(child.f)
打印
this is father
this is child
setmetatable(child,father); // 相当于把child表继承father表(相同方法名不会覆盖);
setmetatable方法准确来说不是把表合并了,只是用child调用字段或方法时,先查找child表如果没有找到就会去father中查找调用。
lua查找一个表元素的规则其实就是如下3个步骤:
1.在表中查找元素,如果找到就返回该元素,找不到则第2步
2.判断该表是否有其他元表,如果没有元表,返回nil,有元表则继续第3步
3.判断元表有没有__index,如果__index为nil,则返回nil;如果__index是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值
3.继承实现
父类实现 classFathe.lua
classFather ={
a = 0;
};
classFather.__index = classFather;
function classFather:new(name)
local o = {name = name}; -- 我从创建需要一个新表
setmetatable(0, classFather);
end
function classFather:getA()
return self.a;
end
return classFather;
子类实现
local father = require("classFathe");
local classChild ={
b = 2;
}
function classChild:new()
-- 实例化父类
local obj = father:new("child");
-- 获取到父类元表
local fatherTable = getmetatable(obj);
-- 实现继承
setmetatable(classChild,obj);
-- 拿个新表来存放父类方法 以便调用被覆盖的方法 self.fathe.getA(self);
obj.father = setmetatable({},fatherTable);
-- 拿到子类的实例(table)
return setmetatable(obj, {__index = classChild})
end
-- 覆盖父类方法
function classChild:getA()
-- 调用父类已经被覆盖的方法
local a = self.father.getA(self);
return a;
end
-- 子类方法
function classChild:gerB()
return self.b
end
调用实现 text.lua
local father = require("classFathe")
local child = require("classChild")
local c = child:new()
-- 从father继承的getA方法
c:getA();
-- child自己的方法。
c:getB();