1

I'm taking a course in Pharo (Smalltalk implementation). There is a small detail I don't really understand about the language.

The professor speaks of late self binding and static super binding. From what I understand of static binding the compiler knows at compile-time what my super class is. This seems logical as there is no multiple inheritance (as far as I know by now) so there can only be one super. So it just has to look at the inheritance tree and take the parent.

The late self binding is something I don't quite grasp. How I see it, is that the compiler can know which class it's compiling if you will, so it knows the type. So why can't it determine if it's compiling class Foo, that self is pointing to Foo? That is, if self always points to the current instance of the class Foo?

4

2 回答 2

1

您关于Smalltalk(或Java 用语中的this )中self的后期绑定(又名动态绑定)的问题是编译器无法知道 self 指的是什么类。

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

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

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

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

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包含一个 class 的实例Foo,所以m()在 class 上实现的方法Foo将被调用。对上面的第二次调用m()表现不同,因为同时z已重新分配并且现在包含 class 的实例Bar,因此将调用m()在 class 上实现的方法。Bar

问题是您仅在运行时才知道z实际包含的对象实例类型。因此,根据接收者对象的实际m()类型(在我们FooBar示例中:取决于变量中包含的对象z)。

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

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

于 2021-10-09T07:59:52.517 回答
0

因为 ifBar是 的子类Foo,并且方法baz定义在 中Foo,所以您可以baz从 的实例调用Bar,在这种情况下,类self将是 Bar,而不是Foo

于 2013-09-30T16:05:03.827 回答