当前位置: 首页 > 知识库问答 >
问题:

后期自装订和静态装订

孙经艺
2023-03-14

我正在学习Pharo(Smalltalk实现)课程。关于这门语言,有一个小细节我不太明白。

教授谈到了后期自绑定和静态超级绑定。根据我对静态绑定的理解,编译器在编译时知道我的超级类是什么。这似乎是合乎逻辑的,因为没有多重继承(据我现在所知),所以只能有一个超级。所以它只需要查看继承树并获取父类。

后期自我绑定是我不太理解的东西。在我看来,编译器可以知道它在编译哪个类,所以它知道类型。那么为什么它不能确定它是否在编译类Foo,那个self指向Foo?也就是如果self总是指向类Foo的当前实例?

共有2个答案

胡承载
2023-03-14

因为如果BarFoo的子类,并且 方法在 中定义,那么可以从 实例调用 ,在这种情况下, Bar,而不是 Foo

王云
2023-03-14

关于Smalltalk中self的后期绑定(也称为动态绑定)(或者用Java的说法),您的问题是编译器如何无法知道self所指的类。

答案是,在任何支持后期或动态绑定的面向对象语言(如果不是全部的话,也是大多数面向对象语言)中,在您开始发送消息之前,您不知道自己(或这个)将绑定到什么。让我们用一个简单的伪代码示例来说明这一点,您可以将其翻译成您最喜欢的任何面向对象语言。

class Foo :
    method m :
        print "Hello, I am foo"

class Bar subclass-of Foo :
    method m :
        print "Hello, I am bar"

因此,假设我们有一个实现某个方法 m 的类 Foo 和另一个类 Bar,其中 Foo超类,它也实现了方法 m 但具有不同的行为。现在假设,我们有一个 Foo 类型的变量 z,我首先为其分配一个 Foo 类型的对象实例,然后稍后再分配一个 Bar 类型的对象实例。到目前为止,没有问题:由于 Bar 是 Zork 的一个子类,由于可替代性原则,它的实例可以在任何需要 Zork 类型的实例的地方使用。特别是,您可以将名为 m 的消息发送到 Zork 对象或 Bar 对象。

z = new Foo()    % z now contains an object of type Foo
z.m()            % This will print "Hello, I am foo"
z = new Bar()    % z now contains an object of type Bar (subclass of Foo)
z.m()            % This will print "Hello, I am bar"

然而,如上面的说明所示,执行m()的结果将取决于变量z中实际存储的对象类型,您只能在运行时知道这一点。在第一次调用上面的m()时,z包含类 的实例,因此将调用在类 Foo<-code>上实现的方法 。上述对 m()的第二次调用的行为不同,因为同时 z已被重新分配,现在包含类 Bar实例,因此将调用在类 Bar上实现的方法 m

问题是,您只知道在运行时< code>z将实际包含什么类型的对象实例。因此,选择执行方法< code>m()的哪个版本(类< code>Foo的版本或类< code>Bar的版本)被推迟到运行时,这取决于接收器对象的实际类型(在我们的示例中:取决于变量< code>z中包含的对象的类型/类)。

我希望这能更好地解释晚期或动态绑定的原理,以及为什么不能在编译时确定这一点,而只能在运行时确定。

您可能还想阅读此相关讨论,其中举例说明并讨论了 Java 中静态绑定和动态绑定之间的区别:Java 中的静态绑定与动态绑定

 类似资料:
  • 我在看一个项目,我发现了一些很奇怪的东西。 现在,我认为唯一的两个优点是,在非静态容器中封装时,命名更加清晰,并且可以传递的参数更少。 但我想知道这是不是一个好主意,通过设计来包装静态类与非静态?如果有的话,还有哪些其他原因?因为我认为创建一个静态并对其进行调用是可以的。但是这个项目特意将所有静态类打包;我也不知道为什么。

  • 有以下代码: 它打印: 12 这个不能编译。为什么?

  • 继续主题泽西岛2 HK2 - @ApplicationScoped不起作用。 我已经知道如何绑定类,以便正确地它们。 你有什么想法,如何自动化这个过程?在我的应用程序中,将每个服务都放在语句中似乎非常难闻。

  • 爱是恒久忍耐,又有恩慈;爱是不嫉妒,爱是不自夸,不张狂,不作害羞的事,不求自己的益处,不轻易发怒,不计算人的恶,不喜欢不义,只喜欢真理;凡事包容,凡事相信,凡事盼望,凡事忍耐。(1 CORINTHIANS 13:4-7) 多态和封装 “多态”和“封装”是OOP的重要特征——前面说的“继承”也是。但是,对于Python而言,对这两个的理解也有很多不同。建议读者“吃百家宴”,到网上搜一搜有关话题,不少

  • 两者的计算结果都为false。(顺便说一句,比较是不必要的,因为类不会重写Object中的equals。) 和都是,因为它们可比,没有错误。比较两个具有不同声明的泛型类型的对象是非法的。 在进一步检查时,字段将通过调用包私有的本机方法,如下所示: 除了Java文档对“表示基元类型”的模糊暗示之外,我找不到任何关于这方面的文档。这个领域有什么用处吗?它在包装类本身中没有使用。 (编辑) 是真的。 还

  • 问题 你想给类或静态方法提供装饰器。 解决方案 给类或静态方法提供装饰器是很简单的,不过要确保装饰器在 @classmethod 或 @staticmethod 之前。例如: import time from functools import wraps # A simple decorator def timethis(func): @wraps(func) def wrapp