写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