zoukankan      html  css  js  c++  java
  • (原创) 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

  • 相关阅读:
    Xcode4快速Doxygen文档注释 — 简明图文教程
    iOS6 旋转
    echart 判断数据是否为空
    echart tootip使用技巧
    下拉菜单自动向上或向下弹起
    前后台数据交互
    打包代码
    echart 设计宽度为百分比时,div撑不开
    无缝滚动(小鹏写)
    内置对象-Request对象
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/3984749.html
Copyright © 2011-2022 走看看