I'm sorry, this question may be a bit long because I want to describe the problem and my understanding as much as precisely.
Recently I'm learning Scala's trait system.
I did some experiments about conflicting members, see the following code:
trait TA {
def play() = println("TA play")
}
trait TB {
def play() = println("TB play")
}
trait TC {
def play() = println("TC play")
}
class MyClass extends TA with TB with TC {
}
Of course, this code compile failed as expected:
Error:(13, 8) class MyClass inherits conflicting members:
method play in trait TB of type ()Unit and
method play in trait TC of type ()Unit
(Note: this can be resolved by declaring an override in class MyClass.)
class MyClass extends TA with TB with TC {
^
My understanding is that
The linearization of class MyClass is {MyClass, TC, TB, TA}, but since there is no override on the play of TB and the play of TC, so it compiled failed.
One workaround is mark override on TA, TB, TC, as following:
trait IPlay {
def play()
}
trait TA extends IPlay {
override def play() = println("TA play")
}
trait TB extends IPlay {
override def play() = println("TB play")
}
trait TC extends IPlay {
override def play() = println("TC play")
}
class MyClass extends TA with TB with TC {
}
OK, this code can be compiled successfully as expected.
But what about this:
trait TA {
def play() = println("TA play")
}
trait TB {
def play() = println("TB play")
}
trait TC {
def play() = println("TC play")
}
class MyClass extends TA with TB with TC {
override def play(): Unit = {
println("MyClass play")
super.play()
super[TC].play()
super[TA].play()
super[TB].play()
}
}
(new MyClass).play()
// -- Output:
// MyClass play
// TC play
// TC play
// TA play
// TB play
What surprised me is that this code can also be compiled successfully.
The linearization of class MyClass still be {MyClass, TC, TB, TA} and there is no override on the play of TB and the play of TC, the only difference is that I added an override on play in MyClass.
Why it can be compiled successfully?
Note that Scala is not Java or C#, there is no default behavior of conflicting members.
In Java, if you don't mark a method as @Override, the default behavior is overriding.
In C#, if you don't mark a method as override, the default behavior is hiding.
In Scala, if you don't mark a method as override, there is no default behavior, they should be conflicting members, IMO.
Therefore, I think the above code compilation should be failed, but why it can be successful?
Or my understanding is wrong.
very thanks.