super()无限循环

时间:2014-03-28 19:26:30

标签: ruby inheritance

我在使用Ruby时遇到了一些继承问题。

class A < Hash
    def initialize()
        super()
        createB
    end
    def createB
        @b=B.new
    end
end
class B < A
    def initialize()
        super()
        createB
    end
    def createB
        @b={x,y,z}
    end
end

上面的代码创建了一个无限循环,其中A的实例尝试创建B的实例,然后调用super(),这将创建B的另一个实例,等等。如何从super()拨打B,但不能从createB的{​​{1}}方法拨打A。我考虑过在initialize的行中添加A初始化方法的选项,并且在is_b=false时只运行createB,但这样做非常难看

1 个答案:

答案 0 :(得分:3)

你有没有尝试过,真的吗?此代码无法正确解析。

据我记忆,没有这样的问题,因为B类的createB会完全覆盖A类的createB,所以不会因为创造而没有“循环” “B”型对象将触发A.createB方法。

证明,Ruby 1.9.3:

C:\Users\quetzalcoatl>pry
[1] pry(main)> class A < Hash
[1] pry(main)*   def initialize()
[1] pry(main)*     puts "A.init"
[1] pry(main)*     super()
[1] pry(main)*     createB
[1] pry(main)*   end
[1] pry(main)*   def createB
[1] pry(main)*     puts "A.createB"
[1] pry(main)*     @b=B.new
[1] pry(main)*   end
[1] pry(main)* end
=> nil
[2] pry(main)> class B < A
[2] pry(main)*   def initialize()
[2] pry(main)*     puts "B.init"
[2] pry(main)*     super()
[2] pry(main)*     createB
[2] pry(main)*   end
[2] pry(main)*   def createB
[2] pry(main)*     puts "B.createB"
[2] pry(main)*     @b={:x=>:x,:y=>:y,:z=>:z} # fixed it for you :)
[2] pry(main)*   end
[2] pry(main)* end
=> nil

[3] pry(main)> A.new     /// manually creating A object to see what happens
A.init                   /// <- ...obvious
A.createB                /// <- A.init called createB (from the very same A object)
B.init                   /// <- A.createB just have created NEW object B
A.init                   /// <- that new B.init called its super()==A.init
B.createB                *** <- A.init (base of the new B) called createB (->derived)!
B.createB                /// <- that new B.init called its createB (->derived)
=> {}

[4] pry(main)> B.new
B.init
A.init                   /// <- save as above
B.createB                /// <- save as above
B.createB                /// <- save as above
=> {}
[5] pry(main)>

如您所见,在创建“B”型对象时,从未调用“A”类中的原始方法(标记为***的位置)