簡體   English   中英

Squeak Smalltalk:初始化不適用於從Array派生的類?

[英]Squeak Smalltalk: initialize don't work for class derived from Array?

當談到Squeak Smalltalk時,我有點新手,所以我可能做錯了什么或者對Squeak應該如何工作做出錯誤的假設。 不過,我想知道我哪里出錯了......

我試圖讓類Blower派生自Array。 Blower基本上是一個Array,但帶有一個名為index的附加實例變量和一些方法。 我認為初始化方法會在我創建一個新對象時自動運行,並且它會初始化數組和索引變量,但這似乎不會發生。 如果我稍后“手動”初始化,它會按預期工作。

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.

Inspect-window shows(不是我的預期): \\#( nil nil nil nil nil nil nil nil nil nil ) index: nil

如果我手動運行初始化,Inspect-window是正確的:

blower initialize.

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

那么為什么在創建Blower並正確設置時不會初始化運行? 反正有沒有自動化,所以它發生在創作? IE瀏覽器。 初始化工作?

看看方法ArrayedCollection類>> new。 它會覆蓋new來調用new:0作為參數。 這將替換調用initialize的Behavior中的new的默認實現。 如果您真的想這樣做,請在您的類中實現new和new:作為類方法。 在每種情況下,調用super然后調用initialize。

new
   ^super new initialize

new: sizeRequested
   ^(super new: sizeRequested) initialize

說了這么多,從Array子類化是一個非常糟糕的主意。 問問自己“在我目前使用陣列的任何地方使用鼓風機是否合理?”。 如果沒有,它不是一個好的子類。 無論何時從集合類中進行子類化,您幾乎總是做錯了。 你想要的是一個名為Blower的類,它是Object的子類,包含兩個實例變量 - 一個用於數組,一個用於索引。 您的班級現在將正常初始化。 對於要發送到陣列的任何操作,在Blower中編寫一個方法將其委托給實例變量。

大衛·巴克所說的是正確的,但還有一些事情需要補充,具體針對Squeak:

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

  2. 其他一些可以發送#initialize然后#initialize :(參見SharedQueue)

  3. 但Array類>> new:有一個完全繞過初始化的特定實現(為了速度,已知初始化數組不需要任何內容​​)

正如大衛所說,將子類化為子類通常是一個壞主意,看看Squeak,已經有太多的反例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM