[英]How to make instances of a class in Smalltalk?
I'm new in Smalltalk (VisualAge environment) and I try to make a class that counts number of her instances. 我是Smalltalk(VisualAge环境)的新手,我尝试创建一个计算其实例数的类。 Unfortunately something dosen't work when I override the 'new' method. 不幸的是,当我覆盖'new'方法时,某些东西不起作用。 This is my class code: 这是我的班级代码:
Object subclass: #TestClassB
instanceVariableNames: 'niceVariable '
classVariableNames: 'InstanceCounter '
poolDictionaries: ''!
!TestClassB class publicMethods !
initWithNiceParameter: parameter
|testClassBInstance|
testClassBInstance:= self new.
^(testClassBInstance niceVariable: parameter)!
new
super new.
InstanceCounter isNil
ifTrue: [InstanceCounter := 0]
ifFalse: [InstanceCounter := InstanceCounter + 1].
^self
! !
!TestClassB publicMethods !
niceVariable: anObject
"Save the value of niceVariable."
niceVariable := anObject.
! !
I'd like to create new object with 'initWithNiceParameter' message: 我想用'initWithNiceParameter'消息创建新对象:
TestClassB initWithNiceParameter: 'my super string'
But all I get is error: 但我得到的只是错误:
TestClassB does not understand niceVariable:
It's because 'TestClassB' is also an object and seems it has no 'niceVariable' setter. 这是因为'TestClassB'也是一个对象,似乎没有'niceVariable'设置器。
Do you have any idea how to create objects, when 'new' method is overrided? 当“新”方法被覆盖时,您是否知道如何创建对象?
The implementation of your method new
returns self
. 你的方法new
的实现返回self
。 The value of self
there is the class TestClassB because new
is a class method and self
in a class method is the class itself. self
的值有TestClassB类,因为new
是一个类方法,而类方法中的self
是类本身。
You should return the object that got created by sending super new
: 你应该通过发送super new
来返回创建的对象:
new
|instance|
instance := super new.
InstanceCounter isNil
ifTrue: [InstanceCounter := 0]
ifFalse: [InstanceCounter := InstanceCounter + 1].
^instance
or shorter: 或更短:
new
InstanceCounter isNil
ifTrue: [InstanceCounter := 0]
ifFalse: [InstanceCounter := InstanceCounter + 1].
^super new
Slightly OT, but the #ifTrue:ifFalse is unnecessarily complex. 稍微OT,但#ifTrue:ifFalse不必要地复杂。 The Smalltalk way to initialize class-level variables is in a class-side #initialize* like so: Smalltalk初始化类级变量的方法是在类的#initialize *中,如下所示:
TestClassB class>>#initialize
InstanceCounter := 0
Now, when you load TestClassB into the system, InstanceCounter will be initialized and you can simplify from Johan's short version to: 现在,当您将TestClassB加载到系统中时,InstanceCounter将被初始化,您可以将Johan的简短版本简化为:
TestClassB class>>#new
InstanceCounter := InstanceCounter + 1.
^super new
I was confused because I didn't know if #initialize method is called automatically. 我很困惑,因为我不知道是否自动调用了#initialize方法。 I use VisualAge 7.5 and I noticed, that if you create a new class using GUI (right-click, "new" -> "part...") and then save it, #initialize isn't called automatically! 我使用VisualAge 7.5,我注意到,如果你使用GUI创建一个新类(右键单击,“new” - >“part ...”)然后保存它,#initizeize不会自动调用! Even if you create a instance of your class in workspace. 即使您在工作区中创建了类的实例。 But if you export your class and then load it again, #initialize is called. 但是如果您导出类然后再次加载它,则会调用#initialize。 To be more specific, class definition looks like this: 更具体地说,类定义如下所示:
Object subclass: #InitTest
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''!
!InitTest class publicMethods !
initialize
Transcript show: 'initialize method'; cr.!
new
Transcript show: 'new method'; cr.
^super new.! !
InitTest initialize! "<- it's created automatically"
InitTest initializeAfterLoad!
I think it's very tricky. 我觉得这很棘手。 Do you know how to (re)load a class definition in VisualAge workspace, to be sure that #initialize is called (without writing InitTest initialize )? 你知道如何(重新)加载VisualAge工作区中的类定义,以确保调用#initialize(不编写InitTest初始化 )?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.