lua实现多继承-方式1

原理

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()

测试结果


猜你喜欢

转载自blog.csdn.net/yzf279533105/article/details/80384436