3

我遇到了以下陈述:

(Metaclass class) new. "Uses the new of Behavior but throws error because Metaclass class is singleton"
Metaclass new. "Uses the new of Behavior"

我想这Metaclass class就是Metaclass为什么答案不同?我似乎无法弄清楚方法查找是如何工作的。我需要遵循哪个层次结构树?我在哪里可以找到具有基本类的几乎完整的树?

4

2 回答 2

7

类/元类关系是 Smalltalk 中最复杂的主题之一,但它是所有事物以一致方式组合在一起的优雅的一部分。

方法查找从对象的类(类描述对象)持有的 MethodDictionary 开始,并沿继承链向上进行。

通常,您不应该创建 Metaclass 的新实例,而应该让 IDE/工具为您创建新类(将 #'subclass:...' 发送到现有超类)的副作用。

您可以在 Smalltalk 图像中找到基本类树。细节取决于方言,Squeak 应该有一个“类层次结构浏览器”,可以让你看东西。

下面是一张帮助我形象化关系的图片。

Smalltalk 类层次结构

于 2019-09-12T01:11:15.397 回答
4

信息中有一些魔力#new,理解需要付出一些努力。应该引起我们注意的是:

一个类如何理解#new给定#new的实现Behavior,它不是我们类的超类

例如,Object new创建一个全新的实例,Object即使Object它不是#new(例如Behavior)的根实现者的子类。

为了更好地理解这一点,请注意这Object new不是发送给实例的消息,Object而是发送给类的消息Object。因此查找将从Object属于 a的类开始Metaclass,即Object class

看起来通过元类的查找机制将遵循一条特殊的路径:它从提到的元类开始,比如Object class. 如果它没有找到选择器,它会在继承层次结构中一直向上直到ProtoObject class需要。但是,它并不止于此。它跳到抽象类Class继续查找。从那里它再次跟随层次结构上升。这发生在所有发送到类的消息中,而不仅仅是#new. 在 的情况下Object new,它会在 中找到实现者Behavior

有一些有趣的观察:

当查找到达Class时,它不再是类端搜索,而是实例端搜索。

一个问题仍然存在:

ProtoObject class查找如何从to跳转Class

好吧,实际上根本没有跳跃。会发生什么:

ProtoObject superclass == nil.

ProtoObject class superclass == Class

并且由于查找发送#superclass消息遵循继承链,它会自然地从 过渡到ProtoObject classClass而无需做任何特别的事情。

这里的特殊细节是,对于所有类,除了ProtoObject我们有

AnyClass class superclass == AnyClass superclass class      "<- algebraic commutativity"

但是,ProtoObject情况并非如此,ProtoObjectisnil的超类而是 is 的超ProtoObject classClass

笔记

这也是a具有不是a的超类的唯一情况。这正是解决建模循环性的例外。MetaclassMetaclass

于 2019-09-12T19:21:45.967 回答