Lua 利用元表实现一个类

Object对象

---------------
--object.lua---
---------------

local Object = {}

--构造函数
function Object:Ctor(...)
end

--销毁
function Object:Dispose()
end

Object.__class = Object
Object.__classname = "Object"

return Object

  • 构造:递归构造父类构造,后构造自身
  • 销毁:销毁自身,后递归销毁父类
  • 继承:
    • 查找:__index先查找自身有没这个key,再递归查父类。之后rawset(t,k,v)
    • 新的属性:__newindex直接放自身实例rawset(t,k,v)
---------------
---class.lua---
---------------

--默认基类
local BaseObject = require "object"

--构造对象实例
local function __CtorInstance(c, inst, ...)
    --递归调用父对象构造
    if c.__super then
        __CtorInstance(c.__super, inst, ...)
    end
    
    --调用本身的构造
    if c.Ctor then
        c.Ctor(inst, ...)
    end
end

--销毁对象实例
local function __DisposeInstance(c, inst)
    while c do
        if c.Dispose then
            c.Dispose(inst)
        end
        c = c.__super
    end
end


--[[类继承实现函数
@param base 基类,不填则是 object 
@param sub 子类
@param name 子类的名称。用来标记类实例,做统计用
]]
local function Class(base, sub, name)

    if name == nil or name == "" then
        print("无效类名!!!")
    end
    
    local className = name
    
	--父类
	local baseClass = nil
	if base then
		if rawget(base, "__class") then
			baseClass = base.__class
		else
			log.Error("错误的类型继承,请检查!classname="..className)
		end
	end
	
	if baseClass == nil then
		baseClass = BaseObject
	end

	--子类
	local subClass = sub or {}
	subClass.__classname = className
	subClass.__super = baseClass
	
    --子类实例创建器
    local instCreator = {}
    
    --关联的类名称
    instCreator.__classname = className
    instCreator.__class = subClass
    
    --重写()操作
    setmetatable(instCreator, {
		__call = function(...)     
                       
			--子类实例
			local subInst = {
				__classname = instCreator.__classname, 		--类名称
				__class = subClass, 						--类
			}
            
			--改写子类实例对象的原表,让其从子类或者父类中获取/设置属性、函数
			setmetatable(subInst, {
				
				--当实例对象中没有的时候,就去子类型中去找,子类型中找不到,就会到父类型中去找
				__index = function(t, k)
					local v = subClass[k]
					if not v then
						local super = subClass.__super
						while(super) do
							v = super[k]
							if v then
								break
							end
							super = super.__super
						end
					end
					rawset(t,k,v)
					return v
				end,

				--新的属性,都放到之类实例身上
				__newindex = function(t,k,v)
					rawset(t,k,v)
				end,
                
			})
        
            --构造对象
            function subInst:CtorInstance(...)
                __CtorInstance(subClass, self, ...)
            end
        
            --销毁实例
            function subInst:ReleaseInstance()
                __DisposeInstance(subClass, self)
            end

            --返回子类的实例
            return subInst
            
        end,
        
    })

    --创建实例
    function instCreator:CreateInstance(...)
        
        --创建一个新的对象
        local inst = instCreator()
        
        --构造
        inst:CtorInstance(...)
        
		return inst
        
	end
	
	--返回子类创建器
	return instCreator    
    
end

--返回类继承实现函数
return Class

使用

local class = require "class"

local TestA = {a = 5, b = 10}
local CTestA = class(nil, TestA, "TestA")

local TestB = {a = 666}
local CTestB = class(TestA, TestB, "TestB")	--继承TestA

local varC = CTestB:CreateInstance()
print("a:"..tostring(varC.a).."  b:"..tostring(varC.b))		
-- 输出》》 a:666  b:10

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值