繁体   English   中英

如何在Smalltalk中创建类的实例?

[英]How to make instances of a class in Smalltalk?

我是Smalltalk(VisualAge环境)的新手,我尝试创建一个计算其实例数的类。 不幸的是,当我覆盖'new'方法时,某些东西不起作用。 这是我的班级代码:

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.
! !

我想用'initWithNiceParameter'消息创建新对象:

TestClassB initWithNiceParameter: 'my super string'

但我得到的只是错误:

TestClassB does not understand niceVariable:

这是因为'TestClassB'也是一个对象,似乎没有'niceVariable'设置器。

当“新”方法被覆盖时,您是否知道如何创建对象?

你的方法new的实现返回self self的值有TestClassB类,因为new是一个类方法,而类方法中的self是类本身。

你应该通过发送super new来返回创建的对象:

new
   |instance|
   instance := super new.
   InstanceCounter isNil
       ifTrue: [InstanceCounter := 0] 
       ifFalse: [InstanceCounter := InstanceCounter + 1].
   ^instance

或更短:

new
    InstanceCounter isNil
       ifTrue: [InstanceCounter := 0] 
       ifFalse: [InstanceCounter := InstanceCounter + 1].
   ^super new

稍微OT,但#ifTrue:ifFalse不必要地复杂。 Smalltalk初始化类级变量的方法是在类的#initialize *中,如下所示:

TestClassB class>>#initialize
   InstanceCounter := 0

现在,当您将TestClassB加载到系统中时,InstanceCounter将被初始化,您可以将Johan的简短版本简化为:

TestClassB class>>#new
   InstanceCounter := InstanceCounter + 1.
   ^super new
  • 或者懒洋洋地

我很困惑,因为我不知道是否自动调用了#initialize方法。 我使用VisualAge 7.5,我注意到,如果你使用GUI创建一个新类(右键单击,“new” - >“part ...”)然后保存它,#initizeize不会自动调用! 即使您在工作区中创建了类的实例。 但是如果您导出类然后再次加载它,则会调用#initialize。 更具体地说,类定义如下所示:

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!

我觉得这很棘手。 你知道如何(重新)加载VisualAge工作区中的类定义,以确保调用#initialize(不编写InitTest初始化 )?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM