Mixing multiple traits in Scala

45,223

Solution 1

It is easy, when declaring a class you just use the "with" keyword as often as you want

class CollegeStudent extends Student with Worker with Underpaid with Young

the order of the traits can be important if a trait is changing the behavior of the class, it all depends on traits you are using.

Also if you don't want to have a class which always uses the same traits you can use them later:

class CollegeStudent extends Student
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore

Solution 2

I think that it is very important to explain not only the syntax, but also which role does the ordering of the traits play. I found the explanation in Jason Swartz's Learning Scala (page 177) quite enlightning.

  • A Scala class can extend multiple traits at once, but JVM classes can extend only one parent class. The Scala compiler solves this by creating "copies of each trait to form a tall, single-column hierarchy of the class and traits", a process known as linearization.

  • In this context, extending multiple traits with identical field names would fail to compile, exactly the same "as if you were extending a class and providing your own version of a method but failed to add an override keyword".

And since it determines the shape of the inheritance tree, the linearization order is indeed one very important question to regard. As an example, class D extends A with B with C (where A is a class and B and C are traits) would become class D extends C extends B extends A. The following few lines, also from the book, illustrate that perfectly:

trait Base { override def toString = "Base" }
class A extends Base { override def toString = "A->" + super.toString }
trait B extends Base { override def toString = "B->" + super.toString }
trait C extends Base { override def toString = "C->" + super.toString }
class D extends A with B with C { override def toString = "D->" + super.toString }

A call to new D() would have the REPL print the following:

 D->C->B->A->Base

Which perfectly reflects the structure of the linearized inheritance graph.

Share:
45,223
Omer
Author by

Omer

I blog at http://metaphysicaldeveloper.wordpress.com/, and my profiles around the web: Twitter GitHub Hacker News Linkedin http://www.hackernewsers.com/users/DanielRibeiro.html

Updated on July 05, 2022

Comments

  • Omer
    Omer almost 2 years

    Quick note: Examples from the tutorial Scala for Java Refugees Part 5: Traits and Types.

    Suppose I have the traits Student, Worker, Underpaid, and Young.

    How could I declare a class (not instance), CollegeStudent, with all these traits?

    Note: I am aware of the simplests cases, such as CollegeStudent with one or two Traits:

    class CollegeStudent extends Student with Worker
    
  • Ajay Gupta
    Ajay Gupta over 8 years
    Changing the behavior means to call a trait methods which is implemented and having the same name in multiple traits. So based upon the order of trait it will call that method.