A few notes about using Scala traits as mixins (construction order, overridden methods)

Here are a few notes about using Scala traits as mixins, specifically:

  • The order in which mixed-in traits are constructed
  • The order in which overridden methods in traits are called when multiple traits are mixed in

The order in which mixed-in Scala traits are constructed

Given three Scala traits, A, B, and C:

trait A { println("trait A is constructed") }
trait B { println("trait B is constructed") }
trait C { println("trait C is constructed") }

If you create a class named D by mixing in A, B, and C:

class D extends A with B with C {
    println("class D is constructed")
}

and then create an instance of D:

val d = new D

you’ll see this output:

trait A is constructed
trait B is constructed
trait C is constructed
class D is constructed

Lesson: Traits are constructed in order from left to right, before the class is constructed.

The order in which overridden trait methods are called when multiple traits are mixed in

Next, if you have a base trait named Hello:

trait Hello {
    def hello { println("hello from Hello") }
}

and then define traits A, B, and C to (a) extend Hello, (b) override hello, and (c) call super.hello after their own greetings:

trait A extends Hello {
    override def hello {
        println("hello from A")
        super.hello
    }
}

trait B extends Hello {
    override def hello {
        println("hello from B")
        super.hello
    }
}

trait C extends Hello {
    override def hello {
        println("hello from C")
        super.hello
    }
}

When you create a class D to mixin A, B, and C:

class D extends A with B with C
val d = new D

and then call hello on D:

d.hello

you see this output:

hello from C
hello from B
hello from A
hello from Hello

If you remove the super.hello call from the hello method in C, you’ll only see this output:

hello from C

Lesson: When multiple traits are mixed into a class and they have the same method name, when that method is invoked, the last trait that’s created — the one on the farthest right — is the one that’s called.

Summary

Here’s a summary of the trait/mixin behavior shown in these examples:

  • Traits are constructed in order from left to right, before the class is constructed
  • When multiple traits are mixed into a class and they have the same method name, when that method is invoked, the last trait that’s created — the one on the farthest right — is the one that’s called
    • In that situation, a trait can invoke the same method on the trait created before it by calling super.methodName, such as super.hello in these examples