lua用元表实现类

lua实现类有很多种写法,一般主流的实现方式是使用lua的元表来实现。下面举一个例子来详细解释其原理

--[[
    模拟class的几大基本需求
    1. 支持对象调用成员方法和成员变量
        可以通过 obj:method(...) 调用 class 的函数
            注:obj:method(...) 等同于 obj.method(self, ...)
        但是 obj 内部不应该持有 method
        obj.method 该变量来源应该至少为 getmetatable(obj).__index.method
        先假定 class == getmetatable(obj).__index
        这步 obj 初始化步骤为 
            mtObj.__index = class
            setmetatable(obj, mtObj)
        在 class 里实现的 method,需要调用成员变量时只需要写上 self,则必然引用的是 obj 表里的变量

    2. 支持类实例化对象时调用构造函数
        可以通过 class.new(...) 生成一个 obj ,调用 obj:ctor() 并返回 obj
        
        a)如果写成 class 表内部不包含 new 的形式(这种写法是错误的)
            class.new 该变量来源应该至少为 getmetatable(class).__index.new
            obj:ctor() 为 obj.ctor(self, ...)
            obj.ctor 该变量来源应为 class.ctor == getmetatable(obj).__index.ctor 
            这步 class 初始化步骤为

                local class = {}
                class.ctor = function ()
                    -- empty function
                end

                local mtClassIndex = {}
                mtClassIndex.new = function (...) 
                    local obj = {}
                    local mtObj = {}

                    -- 这里是上一步得出的结论
                    mtObj.__index = class
                    setmetatable(obj, mtObj)

                    obj:ctor(...)
                    return obj
                end
                mtClass.__index = mtClassIndex
                setmetatable(class, mtClass)

            (后面会详细说明为什么是错的)
            
        b)如果写成 class 表内部包含 new 的形式
            直接可以写成
            class.new = function (...)
                local obj = {}
                local mtObj = {}
                mtObj.__index = class
                setmetatable(obj, mtObj)
                obj:ctor(...)
                return obj
            end

    3. 支持类的继承和多态性
        a) obj:baseMethod 它的类没有这个方法时,调用父类的方法(类的继承性)
            class 里没有 baseMethod
            obj.baseMethod 的数据来源为 getmetatable(class).__index.baseMethod
            先假定 class._base == getmetatable(class).__index
            这里 class 应初始化为
                class._base = base
                mtClass.__index = base
                setmetatable(class, mtClass)

        b) obj:derivedMethod 它的类有这个方法,调用子类的方法(优先实现虚拟继承,类的多态性)
            obj.derivedMethod 数据来源为 class,cl
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值