Lua模拟C#的类继承

写Lua的都知道Lua语言本身是不提供类继承这个概念的,但是我们可以根据Lua提供的设置元方法的特性来模拟类的建立

以下是我写的一个模拟C#类继承的Lua方法,即只能继承一个父类,但可以继承多个接口

我这个模拟构造类时,父类一定要放在第一个参数位,后面跟着的都是接口(也可以第一个参数就是接口)

构造类对象时,只会传构造参数去调用父类的构造方法,但是接口不会调用构造方法(C#接口本来就没有构造方法)

注意这里只是模拟,不是完全实现类似C#的类继承,只是模拟,C#的接口是不能实现具体内容的,但是我们这里的模拟接口可以

我们的"’Lua接口"只是概念,就是除去了构造跟析构函数的"Lua类"

不多说了,附上代码以供各位学习参考:

Class.lua:

--保存类类型的虚表
local _class = {}

--类创建方法(类似C#,只能继承一个父类,但多个接口)
function BaseClass(super, ...)
	-- 生成一个类类型
	local class_type = {}
	local interfaces = {...}
	-- 在创建对象的时候自动调用(构造、析构函数)
	class_type.__init = nil   --类体构函数
	class_type.__delete = nil  --类析构函数
	class_type.super = super   --记录类的父类
	class_type.interfaces = interfaces  --记录接口对象
	class_type.supers = {super, ...}  --用于调用父类(接口)方法时用的

 	--生成一个虚拟表,用于找继承相关的东西
 	local vtbl = {}
	_class[class_type] = vtbl
	setmetatable(class_type, {__newindex =
		function(t,k,v)
			vtbl[k] = v
		end
		, 
		__index = vtbl, --用于查找父类(接口)实现
	})

	--确定虚拟表查找函数
	if (super) then
		local indexFunc = nil
		if (#interfaces > 0) then
			indexFunc = function (t,k)
				local ret = _class[super][k]
				if ret then return ret end
				for _,interface in ipairs(interfaces) do
					local ret = interface[k]
					if ret then return ret end
				end
				return nil
			end
		else
			indexFunc = function(t,k)
				local ret = _class[super][k]
				return ret
			end
		end
		if (nil ~= indexFunc) then
			setmetatable(vtbl, {__index = indexFunc})
		end
	end

	--新建对象的函数
	class_type.New = function(...)
		-- 生成一个类对象
		local obj = {}
		obj._class_type = class_type

		-- 在初始化之前注册基类方法
		setmetatable(obj, { __index = _class[class_type] })

		-- 调用初始化方法
		do
			local create 
			create = function(c, ...)
				if c.super then
					create(c.super, ...)
				end
				if c.__init then
					c.__init(obj, ...)
				end
			end

			create(class_type, ...)
		end

		-- 注册一个delete方法
		obj.Delete = function(self)
			local now_super = self._class_type 
			while now_super ~= nil do	
				if now_super.__delete then
					now_super.__delete(self)
				end
				now_super = now_super.super
			end
		end

		--返回新建好的类对象
		return obj
	end

	--调用类的父类方法函数
	class_type.CallSuper = function (self, k, ...)
		local supers = class_type.supers
		for _,super in ipairs(supers) do
			local func = super[k]
			if (func) then
				func(self, ...)
				return
			end
		end
		print(string.format("Can not Find Method [%s] in Class's Supers", k))
	end
 
 	--建类结束,返回类的table
	return class_type
end

BuildClass.lua:
Class = {}

local _Class = Class

_Class.clsTab = {}

--建立类,这个要在每个类文件中写入
function _Class.Build(className, ...)
	local supers = {...}
	if #supers > 0 then
		local super = _Class.clsTab[supers[1]]
		local interfaces = {}
		if (#supers > 1) then
			for i=2,#supers do
				table.insert(interfaces, _Class.clsTab[supers[i]])
			end
		end

		_Class.clsTab[className] = _Class.clsTab[className] or BaseClass(super, unpack(interfaces))
	else
		_Class.clsTab[className] = _Class.clsTab[className] or BaseClass()
	end
	return _Class.clsTab[className]
end

--获取类
function _Class.Get(className)
	if (nil ~= _Class.clsTab[className]) then
		return _Class.clsTab[className]
	else
		print(string.format("Class %s has not import, get failed", className))
	end
end

--快速新建类对象
function _Class.New(className, ... )
	if (nil ~= _Class.clsTab[className]) then
		return _Class.clsTab[className].New(...)
	else
		print(string.format("Class %s has not import, new failed", className))
	end
end


Example.lua

----------------测试类继承---------------
function Example.TestClass()
	local Base = Class.Build("Base")
	function Base:__init( ... )
		print("Base:__init")
	end
	function Base:__delete( ... )
		print("Base:__delete")
	end
	function Base:Print( ... )
		print("Base:Print")
	end

	local BaseA = Class.Build("BaseA", "Base")
	function BaseA:__init( ... )
		print("BaseA:__init")
	end
	function BaseA:__delete( ... )
		print("BaseA:__delete")
	end
	function BaseA:Print( ... )
		BaseA.CallSuper(self, "Print")
		print("BaseA:Print")
	end

	local InterfaceA = Class.Build("InterfaceA")
	function InterfaceA:__init( ... )
		print("InterfaceA:__init")
	end
	function InterfaceA:__delete( ... )
		print("InterfaceA:__delete")
	end
	function InterfaceA:Print()
		print("InterfaceA:Print")
	end

	local InterfaceB = Class.Build("InterfaceB")
	function InterfaceB:__init( ... )
		print("InterfaceB:__init")
	end
	function InterfaceB:__delete( ... )
		print("InterfaceB:__delete")
	end
	function InterfaceB:Debug()
		print("InterfaceB:Debug")
	end

	local ClassC = Class.Build("ClassC", "BaseA", "InterfaceA", "InterfaceB")
	function ClassC:__init( ... )
		print("ClassC:__init")
	end
	function ClassC:__delete( ... )
		print("ClassC:__delete")
	end
	function ClassC:Print( ... )
		ClassC.CallSuper(self, "Print")
		print("ClassC:Print")
	end
	function ClassC:Debug( ... )
		print("ClassC:Debug")
	end

	local cls = ClassC.New()
	cls:Print()
	cls:Debug()
	cls.Delete(cls)

end



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值