保持Ruby OOP干燥

保持Ruby OOP干燥,ruby,Ruby,我对ruby比较陌生。初始化对象是否会自动初始化其父类?我知道您可以手动调用super来调用超类的initialize方法,但是如果您不显式地调用super,这会自动发生吗 在java中会发生这种情况。初始化java对象时,会自动初始化其父类的对象,并自动调用其父类的构造函数 如果ruby中没有出现这种情况,是否意味着新的父类对象不会与子类一起自动创建(初始化) 如果是这样的话,解决我的问题的最佳OOP方法是什么 类B是a的子类。a具有属性Xresult。B的initialize被传递给对象X,

我对ruby比较陌生。初始化对象是否会自动初始化其父类?我知道您可以手动调用super来调用超类的initialize方法,但是如果您不显式地调用super,这会自动发生吗

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


如果ruby中没有出现这种情况,是否意味着新的父类对象不会与子类一起自动创建(初始化)

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

类B是a的子类。a具有属性Xresult。B的initialize被传递给对象X,我们需要使用传递给B的initialize的对象X在A中设置Xresult

一种方法是将X传递给A的initialize,在那里我们可以从X获得Xresult并设置属性。然而要做到这一点,我必须在B的初始化中做一个super(X)。这不会干的。我有很多B样的孩子

但是,如果不显式地调用super,这会自动发生吗

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

一种方法是将X传递给A的initialize,在那里我们可以从X获得Xresult并设置属性。然而要做到这一点,我必须在B的初始化中做一个super(X)。(这不会干的,我有很多B样的孩子)

我认为这是一个完全可以接受的解决办法。复制一行代码(如
super x
)是不可避免的


也就是说,您可以让A的initialize方法调用您在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)
A类
def初始化(x)
@x=x
如果响应,则初始化子类(:初始化子类)
结束
结束
B类
但是,如果不显式地调用super,这会自动发生吗

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

一种方法是将X传递给A的initialize,在那里我们可以从X获得Xresult并设置属性。然而要做到这一点,我必须在B的初始化中做一个super(X)。(这不会干的,我有很多B样的孩子)

我认为这是一个完全可以接受的解决办法。复制一行代码(如
super x
)是不可避免的


也就是说,您可以让A的initialize方法调用您在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)
A类
def初始化(x)
@x=x
如果响应,则初始化子类(:初始化子类)
结束
结束
B类
Java

即使在Java中,只要没有“无参数构造函数”,您也需要手动调用超级构造函数

红宝石

在Ruby中,您需要在子类
initialize
中手动调用
super
。这对我来说似乎很好,因为只有在需要做额外的工作时才重写初始值设定项,这在超类初始值设定项中是无法完成的。 与Java不同,对
super
的调用不需要位于
初始值设定项的第一行

class Child < Parent
  def initialize(a, b, c)
    @b = b
    @something = @a + @c
    super(a)
  end
end
类子类<父类
def初始化(a、b、c)
@b=b
@某物=@a+@c
超级(a)
结束
结束
我编辑这个问题是为了澄清Rpant的一条评论:“在ruby中,方法只是从基类复制到派生类。”

否,方法未从父类复制到子类。
initialize
方法是ruby中的一个普通方法,它没有Java中的特殊行为。如果您提供一个,那么它将被调用。不需要初始化对象或分配内存,这是在
.new
()中完成的

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

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

Java

即使在Java中,只要没有“无参数构造函数”,您也需要手动调用超级构造函数

红宝石

在Ruby中,您需要在子类
initialize
中手动调用
super
。这对我来说似乎很好,因为只有在需要做额外的工作时才重写初始值设定项,这在超类初始值设定项中是无法完成的。 与Java不同,对
super
的调用不需要位于
初始值设定项的第一行

class Child < Parent
  def initialize(a, b, c)
    @b = b
    @something = @a + @c
    super(a)
  end
end
类子类<父类
def初始化(a、b、c)
@b=b
@某物=@a+@c
超级(a)
结束
结束
我编辑这个问题是为了澄清Rpant的一条评论:“在ruby中,方法只是从基类复制到派生类。”

否,方法未从父类复制到子类。
initialize
方法是ruby中的一个普通方法,它没有Java中的特殊行为。如果您提供一个,那么它将被调用。不需要初始化对象或分配内存,这是在
.new
()中完成的

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

在对象上调用方法时,将搜索类层次结构。一旦找到该方法,搜索就会停止并调用该方法