当谈到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.
Run Code Online (Sandbox Code Playgroud)
如果我在工作区中执行以下操作:
blower := Blower new: 10.
blower inspect.
检查窗口显示(不是我的预期):
\#( 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
Run Code Online (Sandbox Code Playgroud)
那么为什么在创建Blower并正确设置时不会初始化运行?反正有没有自动化,所以它发生在创作?IE浏览器.初始化工作?
看看方法ArrayedCollection类>> new.它会覆盖new来调用new:0作为参数.这将替换调用initialize的Behavior中的new的默认实现.如果你真的想这样做,可以在你的类中实现new和new:作为类方法.在每种情况下,调用super然后调用initialize.
new
^super new initialize
new: sizeRequested
^(super new: sizeRequested) initialize
Run Code Online (Sandbox Code Playgroud)
说了这么多,从Array子类化是一个非常糟糕的主意.问问自己"在我目前使用阵列的任何地方使用鼓风机是否合理?".如果没有,它不是一个好的子类.无论何时从集合类中进行子类化,您几乎总是做错了.你想要的是一个名为Blower的类,它是Object的子类,包含两个实例变量 - 一个用于数组,一个用于索引.您的班级现在将正常初始化.对于要发送到阵列的任何操作,请在Blower中编写一个方法,将其委托给实例变量.