Scala “super”在类中是静态绑定的吗?
我正在阅读Martin Odersky等人(2ed)的《Scala编程》中关于特性的一章,我对类中的Scala “super”在类中是静态绑定的吗?,scala,class,traits,Scala,Class,Traits,我正在阅读Martin Odersky等人(2ed)的《Scala编程》中关于特性的一章,我对类中的super静态绑定的语句感到困惑,而在特性中,它是动态绑定的(第220页) 我理解这句话,但说到像这样的例子: val queue = (new BasicIntQueue with Incrementing with Filtering) 在第229页或线性化的完整解释(第234页)中,我认为,super不能静态绑定,因为否则堆叠特性将不可能——即,当类“开始”调用堆叠方法的链时,super已
super
静态绑定的语句感到困惑,而在特性中,它是动态绑定的(第220页)
我理解这句话,但说到像这样的例子:
val queue = (new BasicIntQueue with Incrementing with Filtering)
在第229页或线性化的完整解释(第234页)中,我认为,super
不能静态绑定,因为否则堆叠特性将不可能——即,当类“开始”调用堆叠方法的链时,super
已经解决,无论用户向traits堆栈中添加了什么,它都会直接命中类父级
我错过了什么?:-)super
是否真的静态绑定到其父级
在第229页或线性化的完整解释(第234页)中,我认为super不能静态绑定,因为否则堆叠特性将不可能——即当类“开始”调用已解析super的堆叠方法链时,无论用户向traits堆栈中添加了什么,它都会直接命中类父级
但是在这种情况下,链不是从BasicIntQueue
的方法开始的,而是从过滤开始的。只有当没有混合特征覆盖该方法时,它才从类开始。如果你定义
class MyQueue extends BasicIntQueue with Incrementing with Filtering {
.. // some super calls
}
或
super
将引用BasicIntQueue,并随过滤而递增
,这是静态解决的
但是,递增
中的超级
调用是动态解析的:在递增的基本
中,它们将引用递增的基本
,而在递增的过滤的基本
中,它们将引用带有过滤的基本
,在堆叠类中调用super
方法时,Incrementing没有任何更改,它总是在父特征之一中调用一个特定的方法,对吗?编译器知道对象的确切静态类型,包括它继承的所有特性。所以,就我所见,这里没有任何东西可以阻止静态分派。@Vladimitmaveev,ad.“堆叠类中的方法”。此方法来自类BasicIntQueue
,该方法是为该类编写和编译的,不知道将来如何使用它。然而,super
被重新路由。正如我所说的,也许我在这里遗漏了一些东西。虽然这个方法确实来自于BasicIntQueue
,但它在每个stackable trait中都被覆盖,这意味着每个trait也包含这个方法。您可以在javap
输出中轻松找到它们。无论如何,对于非静态方法,Java字节码中没有静态分派这样的东西。字节码将包含用于常规方法的invokevirtual
,以及用于接口方法的invokeinterface
(invokespecial
用于构造函数,而invokedynamic
用于其他方法)。这些方法仍然必须针对虚拟表进行解决,除非使用一些优化,如内联。这正是我没有写答案的原因-我对术语有点困惑,不确定我们谈论的是同一件事:)但是,是的,JVM上的AFAIU所有内容都是动态调度的,除非进行了优化,与非虚方法相比,C++中没有静态调度之类的东西。对于静态方法,最接近静态分派的是invokestatic
,但它自然不会与traits一起使用。您可以随意混合traits这一事实并不妨碍编译器了解每个变量的类型(因此也就无法确切知道应该调用方法的特征)。想想看——如果编译器不知道类型,它如何检查您的trait堆栈是否正确?谢谢。我想我明白了,这是术语的问题。因为我把线性化看作是super
分辨率“表”的设置。示例--让MyQueue
仅扩展BasicIntClass
,然后将queue
变量声明为newmyqueue,并通过过滤进行递增。你可以认为super
的表就在那里建立(我的理解),但是你可以说super
是固定的,方法的顺序是在那里建立的。
class MyQueue extends BasicIntQueue with Incrementing with Filtering {
.. // some super calls
}
// an anonymous class
val queue = new BasicIntQueue with Incrementing with Filtering {
.. // some super calls
}