2013-01-08 34 views
8

在諸如Java和C++的語言中,我們給構造函數提供參數。Smalltalk初始化變量

你如何在Pharo Smalltalk中做到這一點?

我想是這樣

|aColor| 
aColor = Color new 'red'. 

或者,這是不好的做法,我應該總是做

|aColor| 
aColor = Color new. 
aColor name:= red.d 

回答

12

s hort的答案是,你可以在Smalltalk中完成相同的工作。從調用代碼它看起來像:

aColor := Color named: 'Red'. 

長的答覆是,在Smalltalk中你不用構造函數,至少不是在你的類的名字命名的特殊消息的意義。你在Smalltalk中做的是定義可以實例化和配置實例的類端消息(即類理解的消息,而不是實例[*])。假設你Color類有一個name實例變量,併爲它制定者,該#named:法會等來實現:

(class) Color>>named: aName 
| color | 
color := self new. 
color name: aName. 
^color. 

需要注意以下幾點:

  • 我們正在使用發送到#new消息該類創建一個新的實例。您可以將#new消息視爲創建對象的原始方式(提示:您可以瀏覽消息的實現者以瞭解它是如何實現的)。
  • 我們可以定義許多類方法來創建新的「已配置」實例(例如Color fromHexa:)或返回預先創建的實例(例如Color blue)。
  • 您仍然可以通過執行Color new來創建未初始化的實例。如果您想禁止該行爲,則必須覆蓋#new類消息。

有很多很好的書,你可以在Stef's Free Online Smalltalk Books

[*]這是很自然的瞭解Smalltalk的基礎,由於在Smalltalk的正交性質,因爲一切(包括類)是一個對象。如果您有興趣查看Pharo by Example的第13章或任何其他對Smalltalk中的類和元類的引用。

HTH

+1

更妙的是沒有任何setter以及參數化需要一個初始化方法:'顏色>> #initializeWithName:'在這種情況下。 –

+1

爲了澄清一下,該類是一個對象,該實例是另一個對象。爲了尊重封裝,類不能訪問實例的實例變量 - 除非善意地要求通過消息發送。它非常統一,Smalltalk即將發送消息,即使對於這樣的基本內核任務也是如此。正如FrankShearar所說,在實例一側設置單個消息可能會更好地同時設置所有變量,這取決於程序員的判斷。 –

+0

FrankShearar&aka.nice,感謝您提高答案 –

3

在Smalltalk中所有的成員域都嚴格保密,並分配給他們,你就必須定義分配方法。

Color >> name: aString 
    name := aString 

然後,你可以這樣創建對象:

|aColor| 
aColor := (Color new) 
    name: 'red'; 
    yourself. 

通常以減少冗長的工廠方法用於:

Color class >> withName: aName 
^(self new) 
    name: aName; 
    yourself. 

有了這個,你可以創建這樣新的對象:

|aColor| 
aColor := Color withName: 'red'.