Scala Trait 的线性化
Scala Trait调用super方法的线性化是一个难理解的内容,下面让我通过一段代码来推演线性化过程。
源代码:
package c5soft
class SuperBase {
def show() {
println("Here step to class SuperBase")
println("I'm " + toString + "\n")
}
}
trait TraitBase extends SuperBase {
override def toString = "trait TraitBase"
override def show() {
println("Here step to trait TraitBase")
super.show()
}
}
trait A extends TraitBase {
override def toString = "trait A"
override def show() {
println("Here step to trait A")
super.show()
}
}
trait AChild extends A {
override def toString = "trait AChild"
override def show() {
println("Here step to trait AChild")
super.show()
}
}
trait B extends TraitBase {
override def toString = "trait B"
override def show() {
println("Here step to trait B")
super.show()
}
}
trait BChild extends B {
override def toString = "trait BChild"
override def show() {
println("Here step to trait BChild")
super.show()
}
}
class C extends SuperBase {
override def toString = "class C"
override def show() {
println("Here step to class C")
super.show()
}
}
object Main extends App {
println("----------C.show-----")
new C show()
println("----------CA.show-----")
new C with A show()
println("----------CB.show-----")
new C with B show()
println("---------CAB.show----")
new C with A with B show()
println("---------CaB.show----")
new C with AChild with B show()
println("---------CBA.show----")
new C with B with A show()
println("---------CBa.show----")
new C with B with AChild show()
println("---------Cab.show----")
new C with AChild with BChild show()
println("---------Ca.show----")
new C with AChild show()
}
输出结果:
----------C.show-----
Here step to class C
Here step to class SuperBase
I'm class C
----------CA.show-----
Here step to trait A
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait A
----------CB.show-----
Here step to trait B
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait B
---------CAB.show----
Here step to trait B
Here step to trait A
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait B
---------CaB.show----
Here step to trait B
Here step to trait AChild
Here step to trait A
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait B
---------CBA.show----
Here step to trait A
Here step to trait B
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait A
---------CBa.show----
Here step to trait AChild
Here step to trait A
Here step to trait B
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait AChild
---------Cab.show----
Here step to trait BChild
Here step to trait B
Here step to trait AChild
Here step to trait A
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait BChild
---------Ca.show----
Here step to trait AChild
Here step to trait A
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase
I'm trait AChild
仔细分析这段代码与输出结果,你就能明了Trait的super调用是如何线性化的。
已CBa.show为例:
println("---------CBa.show----") //小写的a代表AChild
new C with B with AChild show() //这里等同于(new C with B with AChild).show()
调用过程从右到左并依次调用其基类的过程为:
Here step to trait AChild
Here step to trait A
Here step to trait TraitBase
Here step to class SuperBase
Here step to trait B
Here step to trait TraitBase
Here step to class SuperBase
Here step to class C
Here step to class SuperBase
按照【1.基类调用只出现一次;2.后面出现的基类调用在前面删除】原则处理如下:
Here step to trait AChild
Here step to trait A
Here step to trait TraitBase
Here step to class SuperBase
Here step to trait B
Here step to trait TraitBase
Here step to class SuperBase
Here step to class C
Here step to class SuperBase
最终得到:
Here step to trait AChild
Here step to trait A
Here step to trait B
Here step to trait TraitBase
Here step to class C
Here step to class SuperBase