如果在类定义中包含initialize方法,是否需要显式初始化对象?
答案 0 :(得分:22)
不,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
的默认实现调用initialize
,但完全可能(尽管非常愚蠢)使用实现覆盖或覆盖它不
所以,调用initialize
并不是 Ruby ,它是Class#new
。你可能认为这是分裂,因为Class#new
是Ruby不可或缺的一部分,但重要的是:它不是某种语言魔法。这是一个像任何其他方法一样的方法,就像任何其他方法一样,它可以被覆盖或覆盖以完成不同的操作。
当然,如果您不使用new
创建对象,而是使用allocate
手动执行,则不会调用initialize
。
某些情况下创建对象而不调用initialize
。例如。当dup
或clone
,initialize_dup
和initialize_clone
被调用而不是initialize
时(两者都会调用initialize_copy
) 。通过比较Marshal
对对象进行反序列化时,会直接重构其内部状态(即实例变量被反射设置),而不是通过initialize
。
答案 1 :(得分:1)
是的,它是从new
方法调用的,用于创建对象。
答案 2 :(得分:1)
这取决于你对“显性”的定义。通常你需要,即使没有参数:
object = MyClass.new(...)
在某些情况下,有工厂方法可以生成可以使用的实例,从而创建一种隐式初始化形式:
object = MyClass.factory_method(...)
这会在内部调用MyObject.new
。
有些库有相当不寻常的方法签名,例如:
object = MyClass(...)
object = MyClass[...]
效果是一样的,因为它们可能看起来很奇怪但只是方法调用。