我遇到以下陈述:
(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
,那么答案为何不同?
我似乎无法弄清楚方法查找的工作方式。我需要遵循哪个层次树?在哪里可以找到具有基本类的几乎完整的树?
答案 0 :(得分:7)
类/元类关系是Smalltalk中最复杂的主题之一,但它也是所有事物以一致的方式组合在一起的优雅方式的一部分。
方法查找从由对象的类(类描述对象)持有的MethodDictionary开始,并沿继承链向上进行。
通常,您不应该创建新的Metaclass实例,而应该让IDE /工具为您创建Metaclass,这是创建新类的副作用(将#'subclass:...'发送到现有的超类) 。
您可以在Smalltalk映像中找到一棵基本类树。详细信息取决于方言,Squeak应该具有“类层次结构浏览器”,使您可以查看事物。
以下是可帮助我形象化关系的图片。
答案 1 :(得分:4)
消息#new
中有一些魔术,要理解它们需要付出一些努力。应该引起我们注意的是:
在
#new
中实现了#new
的情况下,该类如何理解Behavior
,这不是我们类的超类?< / p>
例如,Object new
创建了Object
的全新实例,即使Object
不是#new
的根实现者的子类(例如{{1} }。
要更好地理解这一点,请注意,Behavior
不是发送到Object new
实例的消息,而是发送到类Object
的消息。因此,查找将从Object
的类Object
开始,即Metaclass
。
似乎通过元类的查找机制将遵循一条特殊的途径:它始于暗指的元类,例如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
的。这正是解决建模圆度问题的例外。