【问题标题】:Why are Metaclasses instances of Metaclass and not Class?为什么 Metaclasses 是 Metaclass 的实例而不是 Class?
【发布时间】:2010-12-10 21:52:51
【问题描述】:

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

【问题讨论】:

    标签: smalltalk pharo


    【解决方案1】:

    简短的回答是“您认为类是系统范围类的实例的假设是错误的,每个类实际上是类特定元类的一个实例”并且“它不会以任何其他方式工作”。

    对答案的轻微修改是“这些名字真的很混乱,有时只记住他们的角色而不是想太多关于他们是如何工作的更容易”。

    短毛回答:

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

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

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

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

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

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

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

    整洁,嗯?

    【讨论】:

    • 当然,如果你完全取消课程,ala selflanguage.org,你永远不必担心这样的远程事情。
    • 是的,但为什么 Metaclasses 是 Metaclass 的实例而不是类?
    • 哎呀,我的手指头晕了……这是一个命名约定。点也是 Point 的实例。
    • metaclass classmetaclass 的一个实例,并且有点短路是可以的,但是为什么要说“来自虚拟机”? classmetaclassmetaclass class 都继承自 behavior(然后有一个方法字典),所以一切都很好,不是吗?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这是我完全理解的事情之一......直到我不得不解释它;-)经过多次蒸馏......

      给定:

      • 对象的行为由其类指定
      • 类也是对象
      • 常规对象/类的行为只对常规对象/类有意义

      因此,类和实例应该有不同的行为说明符(即类)。

      换个角度看,我们所说的“实例端”代表的实例端。我们所说的“类端”代表元类的实例端。

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

      要深入了解细节,请参阅“Pharo 示例”或“Smalltalk 编程技术基础”

      【讨论】:

        猜你喜欢
        • 2016-04-02
        • 1970-01-01
        • 2018-01-04
        • 2021-04-15
        • 1970-01-01
        • 1970-01-01
        • 2022-07-21
        相关资源
        最近更新 更多