11

如果类定义中包含初始化方法,是否需要显式初始化对象?

4

3 回答 3

23

不,Ruby 不会initialize自动调用。

的默认实现Class#new看起来有点像这样:

class Class
  def new(*args, &block)
    obj = allocate
    obj.initialize(*args, &block)
    obj
  end
end

[其实initializeprivate默认的,所以你需要使用obj.send(:initialize, *args, &block).]

因此,Class#new 确实call的默认实现initialize,但是完全有可能(尽管非常愚蠢)用没有的实现覆盖或覆盖它。

因此,调用的不是Rubyinitialize,而是Class#new. 您可能会认为这很麻烦,因为Class#new它是 Ruby 不可或缺的一部分,但这里重要的是:它不是某种语言魔法。它是一种与任何其他方法一样的方法,并且与任何其他方法一样,它可以被覆盖或覆盖以执行完全不同的操作。

而且,当然,如果您不使用new创建对象而是使用手动创建对象allocate,那么initialize也不会被调用。

某些情况下,无需调用即可创建对象initialize。例如,当duping 或cloneing 时,initialize_dupandinitialize_clone被调用而不是initialize(两者都调用initialize_copy)。并且当通过 反序列化对象时,Marshal直接重建其内部状态(即实例变量被反射设置)而不是通过initialize

于 2013-04-27T00:22:04.197 回答
1

是的,它是从new用于创建对象的方法中调用的。

于 2013-04-26T21:15:06.837 回答
1

这取决于您对“显式”的定义。通常你需要,即使没有参数:

object = MyClass.new(...)

在某些情况下,有一些工厂方法可以生成您可以使用的实例,从而创建一种隐式初始化形式:

object = MyClass.factory_method(...)

这将产生MyObject.new内部调用的效果。

有一些库具有相当不寻常的方法签名,例如:

object = MyClass(...)
object = MyClass[...]

效果是一样的,因为这些可能看起来很奇怪,但只是方法调用。

于 2013-04-26T21:16:14.913 回答