I have this code:
trait base{
def msg: Unit= {
println{"base"}
}
}
trait foo extends base {
abstract override def msg: Unit ={
super.msg
println("foo")
}
}
class base2{
def msg:Unit = {
println{"base 2"}
}
}
class test extends base2 with foo{
override def msg: Unit ={
super.msg
println("done")
}
}
If I call (new test).msg
, this prints out things like: base, foo, done
However, if I change the base trait to:
trait base{
def msg: Unit
}
it prints out things like: base 2, foo, done
I understand the order of with
is from right to left (last one comes first) but how about extends
? How come sometimes it prints base2
, but sometimes base
?
Traits are compile-time external values (rather than code generated from an external source). The difference is subtle. Mixins add logic, Traits add data such as compile-time type information.
In scala, trait mixins means you can extend any number of traits with a class or abstract class. You can extend only traits or combination of traits and class or traits and abstract class. It is necessary to maintain order of mixins otherwise compiler throws an error.
Unlike inheritance, however, a class can “mix in” any number of traits. With inheritance, only one superclass is allowed per class.
We can extend from multiple traits, but only one abstract class. Abstract classes can have constructor parameters, whereas traits cannot.
When you omit the implementation, base
is a template of a trait and has different evaluation rules. See the Scala specification
Scala has something called type linearization. It defines initialization order. Read here http://eed3si9n.com/constraining-class-linearization-in-Scala
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