Files
JJBB/Assets/Project/Script/LuaScripts/UI/Lua/Common/BaseClass.txt
2024-08-23 15:49:34 +08:00

75 lines
3.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--保存类类型的虚表
--_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