如果类定义中包含初始化方法,是否需要显式初始化对象?
3 回答
不,Ruby 不会initialize
自动调用。
的默认实现Class#new
看起来有点像这样:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
obj
end
end
[其实initialize
是private
默认的,所以你需要使用obj.send(:initialize, *args, &block)
.]
因此,Class#new
确实call的默认实现initialize
,但是完全有可能(尽管非常愚蠢)用没有的实现覆盖或覆盖它。
因此,调用的不是Rubyinitialize
,而是Class#new
. 您可能会认为这很麻烦,因为Class#new
它是 Ruby 不可或缺的一部分,但这里重要的是:它不是某种语言魔法。它是一种与任何其他方法一样的方法,并且与任何其他方法一样,它可以被覆盖或覆盖以执行完全不同的操作。
而且,当然,如果您不使用new
创建对象而是使用手动创建对象allocate
,那么initialize
也不会被调用。
在某些情况下,无需调用即可创建对象initialize
。例如,当dup
ing 或clone
ing 时,initialize_dup
andinitialize_clone
被调用而不是initialize
(两者都调用initialize_copy
)。并且当通过 反序列化对象时,Marshal
直接重建其内部状态(即实例变量被反射设置)而不是通过initialize
。
是的,它是从new
用于创建对象的方法中调用的。
这取决于您对“显式”的定义。通常你需要,即使没有参数:
object = MyClass.new(...)
在某些情况下,有一些工厂方法可以生成您可以使用的实例,从而创建一种隐式初始化形式:
object = MyClass.factory_method(...)
这将产生MyObject.new
内部调用的效果。
有一些库具有相当不寻常的方法签名,例如:
object = MyClass(...)
object = MyClass[...]
效果是一样的,因为这些可能看起来很奇怪,但只是方法调用。