2013-10-14 43 views
4

對於Squeak Smalltalk,我有點新手,所以我可能會做出錯誤的判斷或對Squeak的工作方式做出錯誤的假設。不過,我想知道我在哪裏出了錯...Squeak Smalltalk:初始化不適用於從Array派生的類?

我試圖讓類鼓風機派生自陣列。鼓風機基本上是一個數組,但有一個額外的實例變量叫做索引和一些方法。我認爲初始化方法會在我創建一個新對象時自動運行,並且它會初始化數組和索引變量,但這似乎不會發生。如果我稍後運行「手動」初始化,它會按預期工作。

Array variableSubclass: #Blower 
instanceVariableNames: 'index' 
(...) 

Blower >> initialize 
super initialize. 
1 to: self size do: [ :ix | self at: ix put: ix ]. 
self shuffle. 
index := 1. 

如果我在工作區中的以下內容: blower := Blower new: 10. blower inspect.

檢查窗口顯示(不出我所料): \#(nil nil nil nil nil nil nil nil nil nil) index: nil

如果我手動運行初始化,檢查窗口是正確的:

blower initialize. 

\#(6 4 1 10 2 8 3 ...) 
index: nil 

那麼爲什麼我在創建鼓風機時不初始化運行並設置它正確嗎? 無論如何要自動化,所以它發生在創作? IE瀏覽器。初始化工作?

回答

5

看看ArrayedCollection類的新方法>> new。它重寫new來調用new:以0作爲參數。這將替換調用初始化的行爲中的新行爲的默認實現。如果你真的想這樣做,實現新的和新的:作爲班級中的類方法。在每種情況下,調用super然後調用initialize。

new 
    ^super new initialize 

new: sizeRequested 
    ^(super new: sizeRequested) initialize 

說了這麼多,從Array中繼承是一個非常糟糕的主意。問問自己:「我現在使用陣列的任何地方使用鼓風機是否合理?」。如果不是,它不是一個好的子類。任何時候你從一個集合類中繼承你幾乎總是做錯了。你想要的是一個名爲Blower的類,它是Object的子類,包含兩個實例變量 - 一個用於數組,另一個用於索引。你的班級現在將正常初始化。對於要發送到數組的任何操作,請在Blower中編寫一個方法,將其委派給實例變量。

1

大衛·巴克說什麼是正確的,但有一些事情要添加,具體到吱:

  1. 某些集合調用#initialize:不是在創建實例#initialize(見例如HashedCollection )

  2. 其他一些可以同時發送#initialize然後#initialize:(見SharedQueue)

  3. 但Array類>>新:有一個特定的實現,它完全繞過初始化(爲SAK高速電子,已知有用於初始化數組需要什麼)

正如大衛說,這通常是一個壞主意,繼承陣,看着佳樂,有太多的反例已經。