Files
JJBB/Assets/Project/Script/LuaScripts/UI/Lua/Common/BaseClass.txt

75 lines
3.0 KiB
Plaintext
Raw Normal View History

2024-08-23 15:49:34 +08:00
--保存类类型的虚表
--_class的结构如下_class = { Class_A = vtbl_A, Class_B = vtbl_B}
local _class = {}
--BaseClass(super)
--函数功能创建一个super类的子类类型
--子类类型实现了New方法、设置了当前类的元表包括__index函数和__newindex函数用于索引操作该操作实现了对虚表的索引
--如果是继承自父类那么虚表的元表的索引方法将会在父类super对应的vtbl中去查找键值
function BaseClass(super)
-- 生成一个类类型, 实际上存放类信息
local class_type = {}
-- 在创建对象的时候自动调用
-- 默认的两个属性
--class_type.__init = false
class_type.__delete = false
class_type.super = super
--!!!看此方法时先跳过看完BaseClass的其他定义后再来看此"成员函数
-- 创建接口
-- 子类型class_type创建实例对象的方法
class_type.New = function(...)
-- 生成一个类对象
local obj = {}
obj._class_type = class_type
-- 在初始化之前注册基类方法
-- 即引入基类class_type的虚表vtbl
setmetatable(obj, { __index = _class[class_type] })
-- 注册一个delete方法
if(super and not super.DeleteMe) then
obj.DeleteMe = function(obj_self)
local now_super = obj_self._class_type
while now_super ~= nil do
if now_super.__delete then
now_super.__delete(obj_self)
end
now_super = now_super.super
end
end
end
-- 调用初始化方法
class_type.__init(obj, ...)
return obj
end
--class_type类型的虚表
local vtbl = {}
--在类类型的虚表中为当前的类类型添加虚表比如使用Layer = Layer or BaseClass() 创建了一个子类Layer那么此时类类型虚表中会添加这么一项_class = { Class_A = vtbl_A, Class_B = vtbl_B, Layer = {}}
_class[class_type] = vtbl
-- 设置class_type的元表给出访问索引函数和赋值索引函数
-- 从赋值索引函数__newindex上可以看出如果要往class_type类型的中添加属性会在其虚表vtbl中实现这种键值的添加
-- 比如Layer = BaseClass()后通过Layer.position = {x = 0.0, y = 0.0} 往Layer中添加一个键值此时该键值会添加在Layer类型所对应的虚表中此时虚表变为_class = { Class_A = vtbl_A, Class_B = vtbl_B, Layer = { position = {x = 0.0, y = 0.0} }}
-- 于是这么做的好处就现象出来了类型Layer自身的键值不会发生改变因此可以做为一个“稳定”的基类去派生子类而所有的变化都体现在Layer所对应的虚表vtbl_Layer中这样的设计封装了变化也便于继承的实现
setmetatable(class_type, {__newindex =
function(t,k,v)
vtbl[k] = v
end
,
__index = vtbl, --For call parent method
})
--如果是通过super派生子类那么vtbl的访问索引将在super的vtbl中查找
if super then
setmetatable(vtbl, {__index =
function(t,k)
local ret = _class[super][k]
--do not do accept, make hot update work right!
--vtbl[k] = ret
return ret
end
})
end
return class_type
end