Smalltalk正在向班级发送消息吗?

问题描述

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

解决方法

您已经注意到,每个类也是一个对象。如果您评估并检查Object,将会看到它。您还可以查找类的类:Object class。它是Metaclass的实例,它具有与其他任何Behavior一样的方法字典,因此其实例(即类对象)可以响应消息。

在系统浏览器中查看类时,可以在实例方法和类方法之间切换视图。您可以在课堂上直接将消息发送给课堂。


Java中的静态方法与Smalltalk中的类方法相似,但是它们并不完全相同。例如,您不能覆盖Java中的静态方法。在Smalltalk中,您可以重写子类中的类方法。您将在系统中看到一些覆盖new的类。之所以可行,是因为元类就像常规类一样相互继承。元类层次结构与类层次结构平行:CollectionObject的子类,而Collection classObject class的子类。因此,Collection类方法可以覆盖Object类方法。在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中编写相同的内容,则自A,foo消息发送self bar将由B的元类调度,因为您已将foo消息发送给B。由于B类重新定义了方法{ {1}}与上面类似,它将改为调用B的类方法,而不是A的类方法,因此打印“ B”。

此差异的另一个症状是,您不能在Java的静态方法中使用bar

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...