smalltalk中的变量类型

时间:2015-06-21 17:11:55

标签: smalltalk squeak gnu-smalltalk

我需要帮助理解Smalltalk中变量的用法和差异。 下面给定代码中每个变量的区别和用法是什么?

Object subclass: #MyClass
  instanceVariableNames: 'x'
  classVariableNames: 'Yy'
  poolDictionaries: ''
  category: 'helpMe'

MyClass class
  instanceVariableNames: 'zzz'

3 个答案:

答案 0 :(得分:10)

实例变量(x)是实例的本地变量。类和任何其他实例都不能访问该变量。

类变量(Yy)是类的本地,所有实例,所有子类和所有子实例(因此整个层次结构)。任何子类或子实例都可以看到该变量的值。

类实例变量(zzz)是类的本地变量。只有定义变量的类才能访问它,实例和子类都不能看到变量(尽管子类继承变量的声明,它们的变量将具有不同的值)。 类也是Smalltalk中的对象。因此,您可以像考虑实例变量一样考虑类实例变量:没有其他实例(类的实例)可以看到该值。感谢@Amos M. Carpenter指出这一点。

答案 1 :(得分:3)

变量是标识符。变量保存对某个对象的引用。

instanceVariableNames :此处x属于某个类的实例。

classVariableNames :这里Yy有一个与所有类的所有实例共享的变量的副本,它可以是一个静态的变量。 因此x可以在不同对象之间具有不同的值。但Yy只能有一个值。

poolDictionaries :在smallTalk中创建,以提供对一组类之间共享的变量的访问

类别' helpme'是一个相关类的集合,如果你创建没有类别的类;使用空白类别创建类。

子类有自己的 instanceVariableNames(zzz),也有继承属性。

答案 2 :(得分:0)

为避免非小人物混淆: 你输入的是一个消息(到Object类),要求它创建一个自己的子类,名为'MyClass',带有一个名为'x'的实例变量(一个实例私有槽)和一个名为'Yy的类变量”。接下来是一个消息,刚刚创建的类定义了一个类实例变量(这是类对象中的一个插槽 - 而不是它的实例),名为'zzz'。

  • 全局变量
    '对象'和'MyClass'是“全局变量”。这些是可见的 无处不在,并且在全球词典中具有技术上的约束力 (持有键值对)。在旧的实现中,只有一个 这样的字典;在最近的实现中,有多个,它们被称为“命名空间”。在您的示例中,发送给Object类的类定义消息将为“MyClass”名称创建一个新的绑定。

  • 类变量
    'Yy'是一个类变量;这也指一个绑定,但该绑定只在类及其子类中可见,对类方法和实例方法都是可见的(见下文)。所有引用相同的绑定,因此子类将看到相同的值。它们可以在子类中重新定义,但是同样,重新定义子类的所有子类都引用相同的绑定。

  • 实例变量这些是对象的私有槽。 'x'是你的例子中的一个。对象和方法(操作)的布局由子类继承,但当然,每个单独的实例都有自己的值。实例变量对实例方法是可见的(当然)。

  • 类实例变量
    因为类是它们自己的对象(元类的实例),所以它们也可以有私有槽。从技术上讲,它们只是类对象的实例变量,对类方法可见。与实例变量一样,布局和方法由子类继承,但每个(类)都有自己的值。这经常被C ++ / Java人员误解,因为他们的语言中没有相应的构造(也要注意类方法是继承的,可以在Smalltalk中重新定义,而其他语言中的静态函数则不能)

  • 池变量(共享池)
    类似于类变量,因为它们指的是类对象非全局持有的绑定。但是,这些在许多合作类中都可见(类似于另一种语言中的“朋友”)。通过在类定义消息中命名池,其绑定对类和实例方法可见。通常,这些用于定义共享常量。

其他变量类型(代码示例中不存在)是方法本地和块本地。这些引用当前上下文中的槽,这在技术上是方法或块的堆栈帧(继续)(或者在块实际上是闭包的情况下是外部上下文)。

'category'只是该类的一个属性,不要与上述变量混淆。可以将其视为附加到其上的标记,以便在浏览器中实现更好的组织。存储此属性的位置的详细信息是特定于方言的:大多数使用单独的(所谓的“组织”),这是一个字典。但是,至少有一种方言(ST / X)将它保持为类对象的私有槽(在那里,它在某种意义上确实是一个变量)。