(原创) cocos2d-x 3.0+ lua 学习和工作,3 : 子类遍历所有父类特定方法

-- 星月相随倾心贡献~~~

-- 在使用lua继承中,调用父类方法需要人为记住有几层继承关系,非常麻烦,直接上代码:
-- example: 1 
    -- base
    -- 基类

    local Base = class( "Base")

    Base.__index = index

    function Base:ctor(...)
        print( "Base:ctor" )
        print( self.__cname )
    end

    function Base:init( t )
        prite( "Base:init" )
        prite( t )   
      -- ...
    end

    return Base

    -- OneBase
    -- 第一个层次继承
    local OneBase = class( "OneBase", require "Base" )
    OneBase.__index = OndeBase

    function OneBase:ctor(...)
        self.super.ctor( self, ... )  -- 调用父类构造函数
        print( "OneBase:ctor" )
    end

    function OneBase:init( t )
        self.super.init( t )
        prite( "OneBase:init" )
        prite( t )  
        --...
    end

    return OneBase
    
    -- 创建
    createInst( "OneBase", 55 )  -- createInst方法在 (原创) cocos2d-x 3.0 + lua (1)中有描述
    -- 输出结果:
    -- Base:ctor
    -- OneBase
    -- OneBase:ctor
    -- OneBase:init
    -- 55
    -- Base:init    
    -- 55 
    
-- 上面的代码中可以看到在OneBase中有 self.super.ctor( self, ... ) 和    self.super.init( t )调用父类的方法,当创建时会自动调用用ctor方法,之后自动调用init方法。
-- 这个是一层继承,那么增加一层会怎么样?
    -- TwoBase
    -- 第二个层次继承
    local TwoBase = class( "TwoBase", require "OneBase" )
    TwoBase.__index = TwoBase

    function TwoBase:ctor(...)
        self.super.ctor( self, ... )  -- 调用父类构造函数
        print( "TwoBase:ctor" )
    end

    function TwoBase:init( t )
        prite( "TwoBase:init" )
        self.super.init( t )
        prite( t )  
        --...
    end

    return TwoBase
    
    -- 创建
    createInst( "TwoBase", 55 )  -- createInst方法在 (原创) cocos2d-x 3.0 + lua (1)中有描述
    
    -- 输出结果:
    
-- 上面的类继承于 OneBase,创建对象,没有任何输出,跟踪后发现,在OneBase中的,self.super是OneBase自己,进入死循环。
-- OneBase修改如下:
    function OneBase:ctor(...)
        self.super.super.ctor( self, ... )  -- 调用父类构造函数
        print( "OneBase:ctor" )
    end

    function OneBase:init( t )
        self.super.super.init( t )
        prite( "OneBase:init" )
        prite( t )  
        --...
    end
-- 两层继承,OneBase里面的代码修改为两个super,即self.super.super。如果再有一层继承,又要做什么修改???
-- 比如
    local ThreeBase = class( "ThreeBaseBase", require "TwoBase" )
    ...
    return ThreeBase

-- 这是OneBase需要改成self.super.super.super, TwoBase需要修改为self.super.super。   再继续增加继承,整个代码就很难维护了   ----- bug——1

-- 这时,OneBase有林外一个子类: OtherTwoBase,
    local OtherTwoBase, = class( "ThreeBaseBase", require "OneBase" )
    ...
    return OtherTwoBase
-- 这个子类只有两层继承关系,而ThreeBase中有三层继承关系。
-- 如果:OneBase里面用self.super.super,那么OtherTwoBase能创建,但是ThreeBase将无法创建。同样,如果改成 self.super.super.super, 则 OtherTwoBase无法创建  ---- bug——2

-- 这两个bug该怎么解决?
-- 思考后,发现,有没有一个公共的方法,只要传递子类的对象就去遍历所有继承关系父类(单一继承)的方法。实现如下:

-- 遍历所有:构造函数
function ergSuperCtor( obj, ... )
    if obj then
        local function again( obj2, ... ) 
            if obj2 and obj2.cotr then
                again( obj2.super, ... )   -- 这两个顺序不能反,原理是:父类的构造函数要先被创建。。。
                obj2.ctor( self, ... )
            end
        end
        again( obj.super, ... )
    end
end
-- 遍历所有:init函数
function ergSuperInit( obj, ... )
    if obj then
        local function again( obj2, ... ) 
            if obj2 and obj2.int then
                again( obj2.super, ... )   -- 这两个顺序不能反,原理是:父类的构造函数要先被创建。。。
                obj2.init( self, ... )
            end
        end
        again( obj.super, ... )
    end
end

-- 通过上面的方法,就只需要在最外层调用,就可以遍历父类所有方法。
-- 注意:父类中不需要在有:self.super 等调用父类的命令。

-- 作者:希望获得各位大神的帮助
-- 问题:
    1. 有没有方法能实现:将函数作为参数,只有一个遍历函数,用户自己能自由制定遍历那个函数的方法?
    -- 例如:
    -- 遍历所有:fc函数
    function ergSuperFc( obj, fc, ... )
        if obj then
            local function again( obj2, ... ) 
                if obj2 and obj2.fc then
                    again( obj2.super, ... )   -- 这两个顺序不能反,原理是:父类的构造函数要先被创建。。。
                    obj2.fc( self, ... )
                end
            end
            again( obj.super, ... )
        end
    end
    -- 作者自己使用了各种方法,传入一个函数作为参数,都没有实现出来,希望能得到各位的指点~~~~
    
    2. 上面两个函数有写代码是重复的,所以有想过做成一个函数,通过传递类型参数调用对应的方法;但是本人考虑的是,一般只有这两个情况,ctor,init需要遍历所有父类,所有就没有这样做,避免用户使用时传递错误参数。
        不过还是写下自己的想法代码,如下:
        
    function ergSuperFc( obj, ty, ... )
        if obj then
            local function again( obj2, ... ) 
                if obj2 then
                    again( obj2.super, ... )   -- 这两个顺序不能反,原理是:父类的构造函数要先被创建。。。
                    local fc
                    if ty == "ctor" then
                        fc = obj2.ctor                    
                    elseif ty == "init" then
                        fc = obj2.init
                    end
                    fc( self, ... )
                end
            end
            again( obj.super, ... )
        end
    end
    
-- 终于把这章写完,希望对各位有帮助~

-- lua我也是初学者,所以有些地方可能写的不好,或者有更好的方法去实现,希望各位能多多指教,多多指导,星月会努力改进!!!

-- 感谢各位花时间阅读本人的作品,谢谢~~~祝各位都能大展宏图,万事顺利~~~下一章节见~~~~

作者使用 cocos2d-x 3.0 + lua学习和工作心得,未经作者允许,请勿转载!在此谢谢各位手下留情~~~

本文没有获得作者本人同意,不得转载,否则必追究相关责任。转载请注明出处!!~~

原文地址:http://www.cnblogs.com/wodehao0808/p/3984749.html