简体   繁体   English

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

[英]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
  • or lazily 或者懒洋洋地

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.

相关问题 如何在Python 3中创建类的新实例? - How make new instances of a class in Python 3? 如何在Smalltalk中打印作为参数发送给类方法的字符串 - How to print a string that is sent as a parameter to class method in smalltalk 如何使用构造函数方法创建一个javascript类来启动新对象/实例? - How to make a javascript class with a constructor method to initiate new objects / instances? Smalltalk:如何实现原语? - Smalltalk: How primitives are implemented? 如何在类中创建静态变量,只能由类修改,而不能由它的实例修改? - How to make static variables inside a class, which can only be modified by the class only and not it's instances? 有没有办法在 python 中创建 class 的多个实例 - Is there a way to make multiple instances of a class in python 如何使不同子类的实例具有其共同父类 class 的相同实例? - How do I make instances of different child classes have the same instance of their common parent class? 如何将实例放入基类 - How to get instances into a base class 如何遍历类实例? - How to iterate through class instances? 我怎样才能允许 class 的所有实例访问 1 个阵列? (C++) - How can i make allow all instances of a class access 1 array? (C++)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM