我遇到了以下几句话:
(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,为什么答案会不一样呢?我似乎不明白方法查找是如何工作的。我需要遵循哪种层次结构树?在哪里可以找到包含基本类的几乎完整的树?
发布于 2019-09-12 09:11:15
类/元类关系是Smalltalk中最复杂的主题之一,但也是一切如何以一致的方式组合在一起的优雅之处的一部分。
方法查找从对象的类(类描述对象)持有的MethodDictionary开始,并沿着继承链向上进行。
一般来说,您不应该创建新的元类实例,而应该让IDE/工具为您创建一个新类的副作用(发送#'subclass:...‘添加到现有的超类)。
你可以在你的Smalltalk镜像中找到一个基本类的树。细节取决于方言,Squeak应该有一个"Class Hierarchy Browser“,允许您查看内容。
下面是一张帮助我可视化这些关系的图片。

发布于 2019-09-13 03:21:46
消息#new中有一些魔力,它的理解需要一些努力。值得我们注意的是:
既然
#new是在Behavior__中实现的,那么一个类怎么可能理解#new,它不是我们类的超类?
例如,Object new创建了一个全新的Object实例,即使Object不是#new的根实现者(例如Behavior)的子类。
为了更好地理解这一点,请注意,Object new不是发送到Object实例的消息,而是发送到Object类的消息。因此,查找将从作为Metaclass的Object类开始,即Object class。
看起来通过元类的查找机制将遵循一条特殊的路径:它从暗示的元类开始,比如Object class。如果它找不到选择器,那么如果需要的话,它会在继承层次结构中一直向上到ProtoObject class。但是,它并没有止步于此。它跳转到抽象类Class以继续查找。从那里,它再次沿着层次结构向上移动。所有发送到类的消息都会发生这种情况,而不仅仅是#new。在Object new的情况下,它将在Behavior中找到实现者。
有一些有趣的事情可以观察到:
当查找到达
Class时,它不再是类端搜索,而是实例端搜索。
还有一个问题:
如何才能从
ProtoObject class跳转到Class?
好吧,实际上根本没有跳跃。事情是这样的:
ProtoObject superclass == nil.但
ProtoObject class superclass == Class由于查找会发送遵循继承链的#superclass消息,因此它将自然地从ProtoObject class转换到Class,而无需做任何特殊操作。
这里的特别细节是除了ProtoObject之外的所有类
AnyClass class superclass == AnyClass superclass class "<- algebraic commutativity"然而,对于ProtoObject来说情况并非如此,ProtoObject的超类是nil,而ProtoObject class的超类是Class。
备注
这也是唯一的情况,其中一个Metaclass有一个超类,这个超类是而不是a Metaclass。这正是解决建模圆周问题的例外。
https://stackoverflow.com/questions/57898036
复制相似问题