I have a trait that extends two other traits that have the same name for a function but its a bit different from the inside, I want to know how do I know which function will be invoked?
I have trait B
that has print()
, and trait C
that has print()
, if I inherit both of them like this:
trait A extends B with C {
def print()
}
each print printing something else, which print will be invoked?
In the particular case where you have name conflicts, you'll receive a compile time error. Assuming D
is the implementing class:
class D extends A with C with B
def main(args: Array[String]): Unit = {
val d = new D
println(d.print())
}
You'll see:
Error:(25, 9) class D inherits conflicting members:
method print in trait B of type ()Unit and
method print in trait C of type ()Unit
(Note: this can be resolved by declaring an override in class D.)
class D extends A with B with C
However, If we help out the compiler by adding an override print()
to D
, and make it call super.print()
, it will print the last trait in the linage which support a print
method, i.e.:
trait A { }
trait B { def print() = println("hello") }
trait C { def print() = println("world") }
class D extends A with B with C {
override def print(): Unit = super.print()
}
We'd get "world". If we switched B
and C
:
class D extends A with C with B {
override def print(): Unit = super.print()
}
We'd get "hello".
One of the most important features of Traits in the original Schärli, Ducassé, Nierstrasz, Black paper is conflict resolution via renaming and hiding. This feature is completely absent from Scala's Traits.
In Scala, conflicts are simply not allowed. They are detected and rejected by the type system. (The original paper was in the context of Smalltalk, which doesn't have a type system, so a different approach was used.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With