原理
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()
测试结果