Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 如何在Smalltalk中创建类的实例?_Oop_Constructor_Smalltalk_Visual Age - Fatal编程技术网

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

Oop 如何在Smalltalk中创建类的实例?,oop,constructor,smalltalk,visual-age,Oop,Constructor,Smalltalk,Visual Age,我是Smalltalk(VisualAge环境)的新手,我尝试创建一个类来统计她的实例数。不幸的是,当我重写“新”方法时,有些东西不起作用。这是我的班级代码: Object subclass: #TestClassB instanceVariableNames: 'niceVariable ' classVariableNames: 'InstanceCounter ' poolDictionaries: ''! !TestClassB class publicMeth

我是Smalltalk(VisualAge环境)的新手,我尝试创建一个类来统计她的实例数。不幸的是,当我重写“新”方法时,有些东西不起作用。这是我的班级代码:

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”setter


当覆盖“new”方法时,您知道如何创建对象吗?

方法的实现
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
稍微有点奇怪,但如果是真的:如果是不必要的复杂。初始化类级变量的Smalltalk方法是在类端#initialize*中,如下所示:

TestClassB class>>#initialize
   InstanceCounter := 0
现在,当您将TestClassB加载到系统中时,InstanceCounter将被初始化,您可以将其简化为:

  • 或者懒洋洋地

    • 我很困惑,因为我不知道是否自动调用了#initialize方法。我使用VisualAge 7.5,我注意到,如果您使用GUI创建一个新类(右键单击“new”->“part…”),然后保存它,“initialize”不会自动调用!即使您在工作区中创建了类的实例。但如果导出类,然后再次加载它,则调用#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!
      
      对象子类:#InitTest
      instanceVariableNames:'
      类变量名称:“”
      池字典:''!
      !InitTest类公共方法!
      初始化
      成绩单显示:“初始化方法”;铬。!
      新的
      成绩单显示:“新方法”;铬。
      ^超级新!
      
      初始化测试!“在我们改进的同时,让我们在类端将InstanceCounter初始化为零#完全初始化并移除分支;#“TestClassB allInstances size”是否不够?@Seandeigris你说的#初始化并移除分支是什么意思?我创建了这个方法(它的类端方法与#new相同),它会覆盖#从对象类初始化,但不会通过创建新对象自动调用它。@BobNamec'TestClassB allInstances size'始终给我1(SmallInteger)@user3452568在注释中解释太难了。我将在回答中向您展示…不应该是
      TestClassB>#new
      类端方法吗?像这样:
      TestClassB class>#new
      ?在Pharo中,典型的方法是如果类已经加载,则只发送``InitTest initialize`。为什么要避免这种情况呢?这只是为了方便反编译开发…我想我现在明白你的问题了。加载类或显式调用类时会调用类端#initialize。实例端#initialize应该从类端#new调用。在Pharo中,这是自动完成的,但不是用其他方言。有关更多信息,请参阅
      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!