(原创) 学习 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

时间: 2024-12-26 06:12:25

(原创) 学习 3 :子类遍历所有父类特定方法的相关文章

继承实现的原理、子类中调用父类的方法、封装

一.继承实现的原来 1.继承顺序 Python的类可以继承多个类.继承多个类的时候,其属性的寻找的方法有两种,分别是深度优先和广度优先. 如下的结构,新式类和经典类的属性查找顺序都一致.顺序为D--->A--->E--->B--->C. class E: def test(self): print('from E') class A(E): def test(self): print('from A') class B: def test(self): print('from B'

Day17:继承实现的原理、子类中调用父类的方法、封装

一.继承实现的原来 1.继承顺序 Python的类可以继承多个类.继承多个类的时候,其属性的寻找的方法有两种,分别是深度优先和广度优先. 如下的结构,新式类和经典类的属性查找顺序都一致.顺序为D--->A--->E--->B--->C. class E: def test(self): print('from E') class A(E): def test(self): print('from A') class B: def test(self): print('from B'

让子类必须重写父类的方法

//在编写子类的时候要重载父类的方法,如果子类不重写方法,则跑出异常让程序崩溃 - (void)superClassMethod { [NSException raise:NSInternalInconsistencyException format:@"It's an exception", NSStringFromSelector(_cmd)]; }

在子类中重用父类的方法或属性

在子类派生出新发方式中重用父类的方法,有两种实现方式1.指名道姓(不依赖继承)# class Hero:# def __init__(self,nickname,life_value,aggresivity):# self.nickname=nickname# self.life_value=life_value# self.aggresivity=aggresivity# def attack(self,enemy):# enemy.life_value-=self.aggresivity##

在子类中显示父类的方法

用super 1 package ppt04; package ppt04; public class Ostrich extends Bird { // 重写Bird类的fly()方法 public void fly() { System.out.println("我只能在地上奔跑..."); } public void callOverridedMethod() { // 在子类方法中通过super来显式调用父类被覆盖的方法. super.fly(); } public stati

在子类中重载父类的方法(重写方法)

<?php class person{ protected $name; protected $sex; protected $age; function __construct($name,$sex,$age){ $this->name=$name; $this->sex=$sex; $this->age=$age; } function say(){ echo "我的名字:".$this->name.":性别:".$this->

继承的顺序,子类覆盖继承父类的方法

当构造一个对象的时候,系统先构造父类对象,再构造子类对象. 构造一个对象的顺序:(注意:构造父类对象的时候也是这几步) ① 递归地构造父类对象: ② 顺序地调用本类成员属性赋初值语句: ③ 本类的构造方法. Super()表示调用父类的构造方法. Super()也和this一样必须放在第一行. This()用于调用本类的构造方法. 如果没有定义构造方法,那么就会调用父类的无参构造方法,即super().

子类重载父类的方法“parent:方法名”

在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法重写. 子类中重载父类的方法就是在子类中覆盖从父类中继承过来的方法,父类中的方法被子类继承过来不就可以直接使用吗?为什么还要重载呢?因为有一些情况我们必须要覆盖的.例如,有一个“鸟”类,在这个类中定义了鸟的通用方法“飞翔”.将“鸵鸟”类作为它的子类,就会将“飞翔”的方法继承过来,但只要一调用“鸵鸟”

python cookbook第三版学习笔记十一:类和对象(二)调用父类的方法

在子类中调用父类的方法,可以下面的A.spam(self)的方法. class A(object):     def spam(self):         print 'A.spam' class B(A):     def spam(self):         print 'B.spam'         A.spam(self) if __name__=='__main__':     b=B()     b.spam() 但是上面的代码有一个问题,如果B的父类变更了,而且有很多子类的父