Squeak Smalltalk:初始化don';对于从数组派生的类不起作用?

Squeak Smalltalk:初始化don';对于从数组派生的类不起作用?,smalltalk,squeak,Smalltalk,Squeak,对于Squeak Smalltalk,我是一个新手,所以我可能会做一些错误的事情,或者对Squeak应该如何工作做出错误的假设。尽管如此,我还是想知道我错在哪里 我试图使类从数组派生。Blower基本上是一个数组,但有一个名为index的附加实例变量和一些方法。我认为当我创建一个新对象时,initialize方法会自动运行,它会初始化数组和索引变量,但这似乎没有发生。不过,如果我稍后“手动”运行initialize,它将按预期工作 Array variableSubclass: #Blower

对于Squeak Smalltalk,我是一个新手,所以我可能会做一些错误的事情,或者对Squeak应该如何工作做出错误的假设。尽管如此,我还是想知道我错在哪里

我试图使类从数组派生。Blower基本上是一个数组,但有一个名为index的附加实例变量和一些方法。我认为当我创建一个新对象时,initialize方法会自动运行,它会初始化数组和索引变量,但这似乎没有发生。不过,如果我稍后“手动”运行initialize,它将按预期工作

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

Blower >> initialize
super initialize.
1 to: self size do: [ :ix | self at: ix put: ix ].
self shuffle.
index := 1.
如果我在工作区中执行以下操作:

鼓风机:=新鼓风机:10。
鼓风机检查。

检查窗口显示(不是我期望的):

\#(零零零零零零零零零零零)
指数:零

如果手动运行初始化,检查窗口是否正确:

blower initialize.

\#( 6 4 1 10 2 8 3 ... )
index: nil
那么,当我创建鼓风机并正确设置它时,为什么不运行初始化呢?
是否有任何方法可以自动执行此操作,以便在创建时执行此操作?例如,使初始化工作?

查看方法ArrayedCollection类>>新建。它将重写new以调用new:并将0作为参数。这将替换调用initialize的new in行为的默认实现。如果您确实想这样做,请在类中实现new和new:as类方法。在每种情况下,先调用super,然后调用initialize

new
   ^super new initialize

new: sizeRequested
   ^(super new: sizeRequested) initialize

说到这里,从数组中生成子类是一个非常糟糕的主意。问问自己“在我目前使用阵列的任何地方使用鼓风机是否合理?”。如果不是,它就不是一个好的子类。每当你从一个集合类中创建子类时,你几乎总是做错了。您需要的是一个名为Blower的类,它是Object的子类,包含两个实例变量——一个用于数组,一个用于索引。您的类现在将正常初始化。对于要发送到数组的任何操作,请在Blower中编写一个方法,将其委托给实例变量。

David Buck所说的是正确的,但还有一些东西需要添加,特别是Squeak:

  • 一些集合调用#initialize:而不是在实例创建时调用#initialize(参见示例HashedCollection)

  • 其他人可以发送两个#initialize然后#initialize:(参见SharedQueue)

  • 但是Array class>>new:有一个完全绕过初始化的特定实现(为了提高速度,我们知道初始化数组不需要任何东西)

  • 正如David所说,将数组子类化通常是一个坏主意,看看Squeak,已经有太多的反例了