Smalltalk 正在向 类 发送消息?

Smalltalk sending messages to Classes?

我在 ProfStef 的教程中注意到,有时消息会发送到 classes 而不是对象。我知道 classes 也是对象,但是如果我没有先创建 class 的实例,class 怎么能查找方法呢?这些方法是在 class 级别定义的吗?类似于 Java 的静态方法?

如您所见,每个 class 也是一个对象。如果您评估和检查 Object,您就会看到它。您还可以查找 class 的 class:Object class。它是 Metaclass 的一个实例,它像任何其他 Behavior 一样有一个方法字典,因此它的实例(即 class 对象)可以响应消息。

在系统浏览器中查看 class 时,您可以在实例方法和 class 方法之间切换视图。 class 端的消息可以直接发送到 class.


Java 中的静态方法与 Smalltalk 中的 class 方法相似,但并不完全相同。例如,您不能覆盖 Java 中的静态方法。在 Smalltalk 中,您可以覆盖 subclass 中的 class 方法。您会在系统中看到一些 classes 覆盖 new。这是有效的,因为 metaclasses 像常规 classes 一样相互继承。 metaclass 层次结构与 class 层次结构平行:CollectionObject 的子class,而 Collection class 是子[= Object class 的 45=]。因此,Collection class 方法可以覆盖 Object class 方法。在 Java 中,您不能依赖静态方法之间的多态性。

例如,您希望打印什么:

public class Main {
    public static void main(String[] args) {
        B.foo();
    }
}

class A {
    public static void foo() {
        System.out.println(bar());
    }
    
    public static String bar() {
        return "A";
    }
}

class B extends A {
    public static String bar() {
        return "B";
    }
}

它将打印“A”。 A.foo 中 bar() 的调用硬连接到 A.bar.

如果您在 Smalltalk 中使用 class 方法编写相同的内容,则 A.foo 中的消息发送 self bar 将由 B 的元 class 发送,因为您已发送发送给 B 的 foo 消息。由于 B class 像上面那样重新定义了方法 bar,因此它将调用 B 的 class 方法,而不是 A 的 class 方法,并且因此打印“B”。

此差异的另一个症状是您不能在 Java.

的静态方法中使用 this