我正在学习Pharo(Smalltalk实现)课程。关于这门语言,有一个小细节我不太明白。
教授谈到了后期自绑定和静态超级绑定。根据我对静态绑定的理解,编译器在编译时知道我的超级类是什么。这似乎是合乎逻辑的,因为没有多重继承(据我现在所知),所以只能有一个超级。所以它只需要查看继承树并获取父类。
后期自我绑定是我不太理解的东西。在我看来,编译器可以知道它在编译哪个类,所以它知道类型。那么为什么它不能确定它是否在编译类Foo,那个self指向Foo?也就是如果self总是指向类Foo的当前实例?
因为如果Bar
是Foo
的子类,并且
方法在
中定义,那么可以从
的实例调用
,在这种情况下,
Bar,而不是
Foo
。
关于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