2013-01-14 29 views
5

在Ruby中,做一個新的類時,我們將定義構造函數方法如下所示:爲什麼我們定義`#initialize`,而不是`:: new`

class Thing 
    def initialize 
    do_stuff 
    end 
end 

然而,在實際製作的實例對象,我們發現我們自己不在實例上調用initialize,而在類上調用new

既然如此,爲什麼我們不定義::new

class Thing 
    def self.new 
    do_stuff 
    end 
end 

有什麼::new確實beind的場面initalize沒有定義?這兩個不同?將定義::new工作?還是僅僅是def initializedef self.new更短?

我在想這個差距一定是有原因的。

+0

http://blog.sidu。in/2007/12/ruby​​s-new-as-factory.html –

回答

10

新爲新對象分配空間並創建它。然後它調用Objects初始化方法來使用分配的內存創建一個新的Object。通常,您想要自定義的唯一部分是實際創建,並且很樂意將後臺內存分配留給Object.new方法,因此您需要編寫一個初始化方法。什麼是新的引擎蓋下做看起來是這樣的(除C):

class Object 
    def self.new(*args, &block) 
     object = allocate 
     object.send(:initialize, *args, &block) 
     return object 
    end 
end 

所以,當你調用Object.new,實際發生的事情是:

1)內存分配 2)調用對象初始化方法。

+0

http://www.ruby-forum.com/topic/61666 –

3
  • 詳細闡述亞伯拉罕的觀點,實際上是顛倒包裝關係。如果您有allocate作爲原語並且通常定義爲new,那麼您總是必須執行常見的操作,例如調用allocate並在最後返回對象,這是一件多餘的事情。通過使用newinitialize,前者將包裝後者,因此您只需定義包裝的內容,而不是包裝。
  • new是一個類方法,所以當你定義它時,默認情況下你沒有訪問實例方法和實例變量,你需要依賴訪問器。另一方面,initialize是一個實例方法,因此使用實例變量和實例方法會更容易。
5

提供對實例變量的訪問。

實例變量(如@value)只能從實例訪問,而不能在類方法中訪問。這與Java等語言不同,其中私有實例變量具有類而不是實例範圍,因此可以從靜態構造函數訪問。

class Thing 
    def initialize 
    @value = 42 
    end 
end 

class Thing 
    def self.new 
    # no way to set the value of @value !!!!!!!! 
    end 
end 

對於那些有興趣在紅寶石的歷史,例如,私人實例變量的對象模型可以追溯到Smalltalk的。你會發現在現代Smalltalk方言中使用相同的模式,例如Pharo,newObject中實現以調用self initialize,使得子類可以容易地初始化實例變量。

+0

這並不改變我討厭不得不使用單詞「初始化」它應該被稱爲post初始化或什麼,在我的世界:) – rogerdpack

相關問題