Smalltalk 为什么元类是元类而不是类的实例?

Smalltalk 为什么元类是元类而不是类的实例?,smalltalk,pharo,Smalltalk,Pharo,我想知道为什么要使用两个不同的类,而不是两个都使用类。一个类显然需要两个类描述:一个用于实例方法,一个用于类方法 现在,您仍然可以尝试对这两个对象使用类。我认为使用元类的一个原因是,您需要区分这两种类型。如果查看方法theMetaClass和theNonMetaClass,您会发现它们是相互镜像的:通过这个类成员从一个元类到另一个类,通过常规类指针(任何对象都有)从一个类到另一个元类。如果他们都是实例类,他们就不知道自己实现了哪一方——除非有一个标志槽,这比创建子类更糟糕。简单的回答是“你认为类

我想知道为什么要使用两个不同的类,而不是两个都使用类。

一个类显然需要两个类描述:一个用于实例方法,一个用于类方法

现在,您仍然可以尝试对这两个对象使用类。我认为使用元类的一个原因是,您需要区分这两种类型。如果查看方法
theMetaClass
theNonMetaClass
,您会发现它们是相互镜像的:通过这个类成员从一个元类到另一个类,通过常规类指针(任何对象都有)从一个类到另一个元类。如果他们都是实例类,他们就不知道自己实现了哪一方——除非有一个标志槽,这比创建子类更糟糕。

简单的回答是“你认为类是系统范围类的实例是错误的,每个类实际上都是特定于类的元类的实例”,而且“它不会以任何其他方式工作”

对答案稍加修改的是“名字真的很让人困惑,有时候只记住他们的角色更容易,而不去想太多他们是如何工作的”

简短的回答:

元类是一个实例,就像所有其他普通Smalltalk类一样,它需要自己的专用类。常规Smalltalk对象的每个实例都有一个类,继承遵循类层次结构。每个类本身都是特定于类的元类的实例,继承遵循元类层次结构。每个元类类本身就是元类类的一个实例,它被虚拟机巧妙地短路了,因为没有人发现给元类类一个父类是有用的,所有尝试过的人都发现他们的理智在这个过程中开始受到侵蚀

更长,仍然毛茸茸的回答:

Smalltalk允许每个类包含特定于类的消息。这些消息大致相当于Java中的静态方法,但有一些显著的区别。其中一个区别是Smalltalk类实际上是实例化对象,它们是系统中的活动对象,具有从其他对象继承的能力,和包含实例变量

此属性导致系统中可能存在多个继承层次结构。常规对象每个都是一个类的实例,消息发送到搜索对象类的对象,然后跟踪类层次结构的继承链。发送到常规对象的消息在类层次结构上解析

此外,类对象是一个特定于类的元类的每个实例。发送到类对象的消息通过查找特定于类的元类,然后在元类层次结构上向上查找来解析

再上一层,元类对象都是系统范围内唯一元类类的实例。发送到元类对象的消息在系统范围内唯一元类中查找,该元类不允许从任何人继承,并且在VM中硬连接为短路

从技术上讲,系统有两个继承层次结构,第三个继承层次结构是用短路伪造的。虽然有很多实际的继承层次结构,但理论上没有理由停在两个层次结构上。这允许每个对象都有自己的、对象唯一的、消息,每个类都有自己的、类唯一的、消息,并强制所有元类只回答元类中定义的一组消息


整洁,是吧?

这是我完全理解的事情之一…直到我不得不解释;-)经过很多提炼

鉴于:

  • 对象的行为由其类指定
  • 类也是对象
  • 常规对象/类的行为仅对常规对象/类有意义
因此,类和实例应该具有不同的行为说明符(即类)

从另一个角度看,我们称之为“实例端”的表示类的实例端,我们称之为“类端”的表示元类的实例端

例如,类定义了#addClassVarNamed:和#addInstVarNamed:,因为它们都在实例端有意义,元类只定义了#addInstVarNamed:,因为没有类端类变量


要深入挖掘细节,请参阅“Pharo By Example”或“Smalltalk编程技术基础”“

当然,如果你完全取消了类,阿拉,你永远不必担心像这样的事情。是的,但是为什么元类是元类的实例而不是类?哎呀,我的手指呆滞了。。。这是一个命名约定。同样,点也是点的实例。那
元类类
元类
的实例,有点短路也可以,但为什么要说“来自虚拟机”?
元类
元类类
都继承自
行为
(然后有一个方法字典),所以一切都很好,不是吗?