Published 2014-02-19.
Last modified 2014-12-16.
Time to read: 3 minutes.
Traits can be ‘stacked’, or mixed together, and this lecture describes how stacked traits work. This lecture also shows how traits can also be used to modify the behavior of any JVM class.

courseNotes/src/main/scala/Traits2.scala
.
Stackable Traits
In Scala, just as in Java, super
for subclasses is determined statically.
Scala traits are much more flexible, and this lecture will explore two ways to work with Scala traits that are beyond anything that Java can do.
Methods defined in traits can override concrete methods defined in classes or traits that they extend.
To do this, the trait’s overriding methods must be decorated with abstract override
.
This is possible because for traits, super
is dynamically determined according to the order in which the trait was mixed in.
When a method is called on a trait, the trait furthest right in the mix which has that method provides the implementation.
If this method calls super
then it invokes the method on the trait on its left, and so on.
In the following example, the Color
trait is not abstract, so the Red
, White
and Blue
traits can
superimpose their two abstract override
methods: color
and paint
on concrete implementations.
The paint
methods are written in such a way that you can see how Scala applies the overrides.
object WhichTrait extends App { trait Color { def color: String = "Unknown" def paint(highlight: String): String = s"$color with $highlight highlights" } trait Red extends Color { override val color: String = "red" override def paint(highlight: String): String = super.paint(s"pink and $highlight") } trait White extends Color { override val color: String = "white" override def paint(highlight: String): String = super.paint(s"light yellow and $highlight") } trait Blue extends Color { override val color: String = "blue" override def paint(highlight: String): String = super.paint(s"bluegreen and $highlight") } val red = new Red{} println(s"""red.paint=${red.paint("polkadot")}""") val redWhite = new Red with White println(s"""redWhite.paint=${redWhite.paint("polkadot")}""") val redWhiteBlue = new Red with White with Blue println(s"""redWhiteBlue.paint=${redWhiteBlue.paint("polkadot")}""") class Concrete extends Red with White with Blue val concrete = new Concrete println(s"""concrete.paint=${concrete.paint("polkadot")}""") }
You can run this program by typing.
$ scala> sbt "runMain WhichTrait"
Output is.
red.paint=red with pink and polkadot highlights redWhite.paint=white with pink and light yellow and polkadot highlights redWhiteBlue.paint=blue with pink and light yellow and bluegreen and polkadot highlights concrete.paint=blue with pink and light yellow and bluegreen and polkadot highlights
The red
variable contains an instance of an anonymous subclass of the Red
trait.
Similarly, the redWhite
variable contains an instance of an anonymous subclass of the Red
and White
traits
mixed together.
The redWhiteBlue
variables contains an instance of an anonymous subclass of the Red
, White
and
Blue
traits.
The concrete
variable contains an instance of the Concrete
class, which is also a mix of the Red
,
White
and Blue
traits.
Although the behavior of redWhiteBlue
is identical to that of concrete
, there is only one class definition for all
Concrete
instances.
In contrast, each time you write Red with White with Blue
a new abstract class definition is created.
When creating the red
variable by using the Red
trait alone, we need to include an empty body to create an anonymous
subclass of Red
, like this.
new Red{}
new Red with White
Notice the order of the colors that are printed out by redWhiteBlue.paint
and concrete.paint
.
- The invocation passes
polkadot
toconcrete.paint
. - The rightmost trait,
Blue
, prependsbluegreen
and invokessuper.paint
. - The next rightmost trait,
White
, prependslight yellow
and invokessuper.paint
. - The next rightmost trait,
Red
, prependspink
and invokessuper.paint
. - The
Color
trait, which is the superclass of theRed
trait, prepends the value ofcolor
. Unlike thepaint
methods, thecolor
methods in each trait do not callsuper
, so that property is consistent for all traits, and it set by the right-most trait that was mixed in.
Abstract Override

The following example defines a trait that extends the mutable java.util.Set[String]
, which is a Java interface that uses generics.
Scala also supports generics, and we will cover that topic in the
Parametric Types lecture of the
Intermediate Scala course.
This code is somewhat ugly because Scala generics are not used.
The IgnoredCaseSet
trait’s overriding add
method converts any incoming String
s to lower case before
adding it to the set.
Other types of objects are merely added to the set without modification.
This code uses isInstanceOf
to test if the runtime type of obj
is a String
, and asInstanceOf
to
typecast obj
to String
if that is its runtime type.
Later in this course we will learn how to use the match
keyword and then we won’t need to use isInstanceOf
any more.
trait IgnoredCaseSet extends java.util.Set[Object] { abstract override def add(obj: Object): Boolean = if (obj.isInstanceOf[String]) super.add(obj.asInstanceOf[String].toLowerCase) else super.add(obj) abstract override def contains(obj: Object): Boolean = if (obj.isInstanceOf[String]) super.contains(obj.asInstanceOf[String].toLowerCase) else super.contains(obj) } class MySet extends java.util.HashSet[Object] with IgnoredCaseSet
Java HashSet
implements Set
, which is why we could subclass HashSet
by mixing in IgnoredCaseSet
above.
Let’s create a MySet
instance that contains String
s, and add mixed case String
s to it.
We will then use the trait’s overriding contains
method to determine if the set contains the equivalent lower case
String
.
scala> val set = new MySet() set: MySet = []
scala> %}set.add("One") res3: Boolean = true
scala> %}set.add("Two") res4: Boolean = true
scala> %}set.add("Three") res5: Boolean = true
scala> %}set.contains("hi there") res6: Boolean = false
scala> %}mySet.contains("two") res7: Boolean = true
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.