Keepinig Ruby OOP DRY

时间:2016-06-16 03:53:57

标签: ruby

我对红宝石比较新。是否有可能初始化对象会自动初始化其父类?我知道你可以手动调用super来调用超类的初始化方法,但如果你没有显式调用super,会自动发生吗?

在java中它会发生。初始化java对象时,会自动初始化其父类的对象,并自动调用其父类的构造函数。

如果在ruby中没有发生这种情况,是否意味着不会自动创建(初始化)新的父类对象以及子类?

如果是这样,那么解决我问题的最佳方法是什么?

B类是A的孩子.A有一个属性Xresult。 B的初始化是通过对象X传递的,我们需要使用传递给B初始化的对象X在A中设置Xresult。

一种方法是将X传递给A的初始化,我们可以从X中获取Xresult并设置属性。但要做到这一点,我将不得不在B的初始化中做一个超级(X)。这不会是干的。我有很多B喜欢孩子。

3 个答案:

答案 0 :(得分:2)

<强>爪哇

即使在Java中,只要没有“no-args构造函数”,你就需要手动调用超级构造函数。

<强>红宝石

在Ruby中,您需要在子类super中手动调用initialize。这对我来说似乎完全没问题,因为如果你需要做额外的工作,你只会覆盖初始化器,这在超类初始化器中是无法完成的。 与Java不同,对super的调用不需要位于initializer的第一行

class Child < Parent
  def initialize(a, b, c)
    @b = b
    @something = @a + @c
    super(a)
  end
end

我编辑问题以澄清 Rpant 的评论:“看起来像在ruby中,方法只是从基类复制到派生类”

不,从父级到子级的方法不会复制initialize方法是ruby中的常规方法,它没有Java中的特殊行为。如果你提供一个,那么它将被调用。初始化对象或分配内存不需要,这可以在.newhttp://ruby-doc.org/core-2.2.0/Class.html#method-i-new)中完成。

未调用超级类initialize的原因在于方法查找路径:

在对象上调用方法时,将搜索类层次结构。一旦找到该方法,搜索就会停止并调用该方法。从那以后,如果需要,您有责任致电super

答案 1 :(得分:1)

  

但如果没有明确调用super,会自动发生这种情况。

不,如果子类有自己的initialize方法,它不会自动发生。但是,如果子类没有定义自己的initialize方法,那么它将继承父类中的方法。

  

一种方法是将X传递给A&#39; s初始化,我们可以从X中获取Xresult并设置属性。但要做到这一点,我将不得不在B的初始化中做一个超级(X)。 (这不会干。我有很多B喜欢的孩子)

我认为这是一个完全可以接受的解决方案。复制像super x这样的单行代码是不可避免的。

话虽这么说,你可以让A的初始化方法调用你在B中定义的方法,如下所示:

class A
  def initialize(x)
    @x = x
    initialize_subclass if respond_to?(:initialize_subclass)
  end
end

class B < A
  def initialize_subclass
    puts 'doing B-specific stuff'
  end
end

B.new(5)
A.new(6)

答案 2 :(得分:1)

补充其他答案:ruby&#39; initialize 一个构造函数。它只是一个普通的方法,与您在类中可能拥有的所有其他方法相同。唯一的区别是当initialize一个对象(作为对象创建过程的一部分)时,new被调用。

如果您在B中使用此方法:

class B < A
  def hello
    puts 'whatever'
  end
end

你不会指望它自动拨打父母hello,你呢?所以有你的答案。