原理
1. lua的面向对象是基于元表metatable实现的,原理即在一个表中查找不到,就到元表中查找
2. lua的多继承原理即在一个表中查找不到,则到多个表中进行查询
代码示例
----------------------------------------- 基类BaseClass1 ------------------------------------------
-- 类BaseClass1的声明
BaseClass1 =
{
x = 0
}
-- 设置metatable的元方法__index,指向表BaseClass1自己
BaseClass1.__index = BaseClass1
-- 构造函数
function BaseClass1:new(x)
print("BaseClass1:构造函数,x = "..x)
-- 新建一个对象,这样通过BaseClass1:new()函数创建的每一个实例都是独立的
local tempObj = {}
tempObj.x = x
-- 设置新对象的metatable,谨记:这一步非常重要
setmetatable(tempObj,BaseClass1)
-- 返回这个新创建的对象
return tempObj
end
-- 类的print()函数
function BaseClass1:Print()
print("BaseClass1:Print() x = "..self.x)
end
-- 类的特有成员函数
function BaseClass1:Add_X(v)
print("BaseClass1:Add_X()")
self.x = self.x + v
end
----------------------------------------- 基类BaseClass2 ------------------------------------------
-- 类BaseClass2的声明
BaseClass2 =
{
y = 0
}
-- 设置metatable的元方法__index,指向表BaseClass2自己
BaseClass2.__index = BaseClass2
-- 构造函数
function BaseClass2:new(y)
print("BaseClass2:构造函数,y = "..y)
-- 新建一个对象,这样通过BaseClass2:new()函数创建的每一个实例都是独立的
local tempObj = {}
tempObj.y = y
-- 设置新对象的metatable,谨记:这一步非常重要
setmetatable(tempObj,BaseClass2)
-- 返回这个新创建的对象
return tempObj
end
-- 类的print()函数
function BaseClass2:Print()
print("BaseClass2:Print() y = "..self.y)
end
-- 类的特有成员函数
function BaseClass2:Reduce_Y(v)
print("BaseClass2:Reduce_Y()")
self.y = self.y - v
end
----------------------------------------- 搜索函数 ---------------------------------------
-- 非常关键的函数(在table list中查找变量key)
local function search(key,list)
for i=1, table.getn(list) do
local v = list[i][key]
if v then
return v
end
end
end
----------------------------------------- 子类SubClass ---------------------------------------
-- 子类SubClass的声明,这里又声明了一个新的变量z
SubClass =
{
z = 0
}
-- 设置metatable的元方法__index,指向表SubClass自己
SubClass.__index = SubClass
-- 构造函数
function SubClass:new(x,y,z)
print("SubClass:构造函数:SubClass,x = "..x..",y = "..y..",z = "..z)
-- 创建一个基类1的对象
local base1 = BaseClass1:new(x)
-- 创建一个基类2的对象
local base2 = BaseClass2:new(y)
-- 创建一个子类的对象
local tempObj = {}
tempObj.z = z
-- 将该对象的元表指向SubClass
setmetatable(tempObj,SubClass)
-- 查找表的集合
local baseClass = {base1, base2}
-- SubClass的元表最终指向两个基类
setmetatable(SubClass,{__index = function(table,key) return search(key, baseClass) end})
return tempObj
end
-- 定义一个子类特有的print()函数
function SubClass:SubPrint()
print("SubClass:SubPrint() x = "..self.x..", y = "..self.y..", z = "..self.z)
end
---------------------------------------- 下面是测试代码 -----------------------------------
-- 构造一个子类实例
local SubObj = SubClass:new(1,2,3)
-- 访问子类自己的print()函数,
--由于基类1和基类2里面都有Print()函数,会发现,实际访问的是基类1里面的函数,非常不建议基类中函数/变量名字一样,容易混淆
SubObj:Print()
-- 访问子类自己的print()函数
SubObj:SubPrint()
-- 访问基类1的特有函数Add_X()
SubObj:Add_X(10)
-- 访问子类自己的print()函数,检测结果
SubObj:SubPrint()
-- 访问基类2的特有函数Reduce_Y
SubObj:Reduce_Y(10)
-- 访问子类自己的print()函数,检测结果
SubObj:SubPrint()
测试结果