2015-06-21 65 views
3

我需要帮助了解Smalltalk中变量的用法和区别。 下面给出的代码中每个变量有什么区别和用法?smalltalk中的变量类型

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

MyClass class 
    instanceVariableNames: 'zzz' 

回答

10

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

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

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

+1

+1,即使我认为有关_class实例变量_的位不太正确。如果我没有记错,只有班级有权访问它们,但不是它的实例。子类继承它们,但有它们自己的值。对于来自其他语言的人来说,这个类通常很难理解,因为类本身并不是真正的对象。 –

+2

是的,你是对的。感谢您指出了这一点。我已经修改了我的答案以包含这一点。 –

3

变量是标识符。一个变量持有对某个对象的引用。

instanceVariableNames:这里x属于一个类的实例。

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

poolDictionaries:在Smalltalk的创建提供访问一组类之间共享变量

类别“helpme”是相关类的集合,如果你没有一个类别创建类;该类将被创建为一个空白类别。

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

0

为了避免混淆非小写字母: 输入的内容是一条消息(Object类),要求它用实例变量创建一个名为'MyClass'的子类,槽)命名为'x'和一个名为'Yy'的类变量。接下来是一个消息给刚刚创建的类,以定义一个名为'zzz'的类实例变量(这是类对象中的一个槽 - 不是它的实例)。

  • 全局变量
    'Object'和'MyClass'是“全局变量”。它们在任何地方都可见,并且在全球词典 (包含键值对)中在技术上是绑定的。在旧的实现中,只有一个这样的字典;在最近的实现中,有多个,它们被称为“命名空间”。在你的例子中,发送给Object类的类定义消息将为'MyClass'名称创建一个新的绑定。

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

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

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

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

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

'category'只是该类的一个属性,不要与上述变量混淆。把它看作是附加在它上面的标签,以便在浏览器中提供更好的组织。该属性存储位置的详细信息是特定于方言的:大多数使用单独的(所谓的“组织”),这是一个字典。但是,至少有一种方言(ST/X)将它作为类对象的专用槽(并且在某种意义上它确实是一个变量)。