Trait linearization in Scala
The problem is which method will be called when stacking trait after class.
First, it’s not allowed to mix in traits with same method in Scala. There will be compile error saying “class XX inherits conflicting members:”.
trait T1 {
def run():Unit = println("T1")
}
trait T2 {
def run():Unit = println("T2")
}
class TraitTest extends T1 with T2
To solve the conflict, base class need to override the conflict method.
trait T1 {
println("cons T1")
def run():Unit = println("T1")
}
trait T2 {
println("cons T2")
def run():Unit = println("T2")
}
class TraitTest extends T1 with T2 {
println("cons trait")
//super referts to T1 or T2?
override def run():Unit = super.run()
}
object TraitTest {
def main(args: Array[String]): Unit = {
// output:
// cons T1
// cons T2
// cons Trait
// T2
new TraitTest().run()
}
}
In order to construct base class, all the super must be constructed first, the construction order is from left to right(see the println output). Right most is the one closed to base class construction, so super is resolved to the right most trait.
Takeaways:
- Construction order is from parent to child or super to sub.
- Construction order is from left to right.
- Method resolve order is from right to left as opposite to construction order. As the right most is the most recent to be constructed, it can override previous method.
- Resolve construction order first to understand method call order.
reference https://stackoverflow.com/questions/34242536/linearization-order-in-scala