Pharo 的对象模型

标签: smalltalk ; pharo ;


Pharo中,类本质上也是一个对象,类这个对象所属的类称为“元类”,即,类是元类的实例。而“元类”本身既是类也是对象。颇有些波粒二象性的味道。作为对象,所有的元类都是Metaclass这个类的实例,而作为类,元类的继承链与对应的实体类的继承链一模一样。

下图就是Pharo的类结构树状图

ProtoObject
  └── Object
        └── Behavior
              └── ClassDescription
                    ├── Metaclass
                    └── Class
                          └── ProtoObject class
                                └── Object class
                                      └── Behavior class
                                            └── ClassDescription class
                                                  ├── Metaclass class
                                                  └── Class class

ProtoObject是所有类的根,同时,ProtoObject也是ProtoObject class这个元类的实例。而ProtoObject class的超类继承链向上追溯,又可以一直追溯到ProtoObject本身。也就是说,Pharo的类结构是递归定义的。

要理解Pharo的继承树还是需要付出一些智力成本的。好消息是,对于应用开发者而言,大部分时间可以忽视元类的存在。唯一要注意的是,元类可以有实例变量,也可以定义方法。元类的方法相当于其它语言的类方法(静态方法),执行的主体是类本身,而不是实例。

在Pharo的类定义中,有三个地方可以用来保存变量:

  • 类本身的定义(实例侧):

    • instanceVariableNames 实例变量,类型为字符串,不同的实例变量用空格分开。在新版的Pharo中,名字改成了slots, 类型改成了数组,变量用符号命名。

    • classVariableNames 类变量,在新版中,名字改成了sharedVariable,同样也是数组。

  • 在元类中定义(类侧):

    • instanceVariableNames 类的实例变量。这个东西是其它语言没有的。

实例变量 都是私有的,只能从实例及子类的实例进行访问;

类变量 在该类的所有实例之间共享;

类实例变量则是类方法唯一可以直接访问的变量。类实例变量可以通过继承链遗传给子类,但是子类拥有自己的状态。