Scala 特质(trait) 的 super 方法调用是动态绑定的

在 Java 或者 Scala 的类中,super.foo() 这样的方法调用是静态绑定的,也就是说当你在代码中写下 super.foo() 的时候就能明确是调用它的父类的 foo() 方法。然而,如果是在特质中写下了 super.foo() 时,它的调用是动态绑定的。调用的实现奖在每一次特质被混入到具体类的时候才被决定。

确切的讲,特质的 super 调用与混入的次序很重要,参照下面的例子说话:

直截的讲就是超靠近后面的特质越优先起作用。当你调用带混入的类的方法是,最右侧特质的方法首先被调用。如果那个方法调用了 super,它调用其左侧特质的方法。可以这么认为,Doubling 的 super 指向了  Incrementing,Incrementing 的 super 指向了 BasicIntQueue。

来看个完整的实例实际体验一把,如果要帮助理解,最好应该实际运行一下这个实例

实例中两次声明 queue1 和 queue2 是采用了不同的顺序混入 Incrementing 和 Doubling 两个特质,执行的效果是不一样,输出分别是 5 和 6。这种对 super 的重新理解会带来冲击,同时很有可能在代码维护时调整混入的特质时引来些许的麻烦。

混入特质存在着一种线性化的次序关系,再来看一下这个线性化的例子:

下图是 Cat 类的继承层级和线性化次序的展示图

继承次序使用白色三角箭头表示,箭头指向超类,黑底箭头说明线性化次序,箭头指向 super  调用解决的方向。

本文链接 https://yanbin.blog/scala-trait-super-dynamic-binding/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments