Scala trait examples and syntax

This page contains a collection of Scala trait examples. I created many of these examples when I was writing the Scala Cookbook. Unlike the Cookbook — where I explain these examples in great detail — on this page I’m just sharing many of the examples so you can use this as a Scala trait reference page. (The Cookbook actually contains more examples than this page.)

Without any more introduction, here are the examples.

Using a Scala trait like a Java interface

A trait can be used just like a Java interface. As with interfaces, just define the methods in your trait that you want extending classes to implement:

trait BaseSoundPlayer {
  def play
  def close
  def pause
  def stop
  def resume
}

Extending Scala traits

If a class implements one trait it will use the extends keyword:

class Mp3SoundPlayer extends BaseSoundPlayer {
  def play   {}
  def close  {}
  def pause  {}
  def stop   {}
  def resume {}
}

One trait can extend another trait:

trait Mp3BaseSoundFilePlayer extends BaseSoundFilePlayer {
  def getBasicPlayer:BasicPlayer
  def getBasicController:BasicController
  def setGain(volume: Double)
}

If a class extends a trait but does not implement the methods defined in that trait, it must be declared abstract:

// must be declared abstract because it does not implement BaseSoundPlayer methods
abstract class JavaSoundPlayer extends BaseSoundPlayer {
  def play   {}
  def close  {}
}

If a class implements multiple traits, it will extend the first trait (or a class, or abstract class), and then use with for other traits:

abstract class Animal {
  def speak
}

trait WaggingTail {
  def startTail
  def stopTail
}

trait FourLeggedAnimal {
  def walk
  def run
}

class Dog extends Animal with WaggingTail with FourLeggedAnimal {
  // implementation code here ...
}

Abstract and concrete fields in traits

In a trait, define a field with an initial value to make it concrete, otherwise give it no initial value to make it abstract:

trait PizzaTrait {
  var numToppings: Int     // abstract
  val maxNumToppings = 10  // concrete
}

In the class that extends the trait, you’ll need to define the values for the abstract fields, or make the class abstract. The Pizza class demonstrates how to override the numToppings field:

class Pizza extends PizzaTrait {
  var numToppings = 0      // override not needed
}

trait PizzaTrait {
  var numToppings: Int     // abstract
  val maxNumToppings = 10  // concrete
}

Using a Scala trait like a Java abstract class

You can use Scala traits like abstract classes in Java. In the following example, an implementation is provided for the speak method in the Pet trait, so implementing classes don’t have to override it. The Dog class chooses not to override it, while the Cat class does:

trait Pet {
  def speak { println("Yo") }   // concrete implementation of a speak method
  def comeToMaster              // abstract
}

class Dog extends Pet {
  // don't need to implement 'speak' if you don't want to
  def comeToMaster { ("I'm coming!") }
}

class Cat extends Pet {
  // override 'speak'
  override def speak { ("meow") }
  def comeToMaster { ("That's not gonna happen.") }
}

If a class extends a trait without implementing its abstract methods, it must be defined abstract. Because FlyingPet does not implement comeToMaster, it is defined abstract:

abstract class FlyingPet extends Pet {
  def fly { ("I'm flying!") }
}

Using traits as simple mixins

To implement a simple mixin, define the methods you want in your trait, then add the trait to your class using extends or with. In the following example we define a Tail trait:

trait Tail {
  def wagTail { println("tail is wagging") }
}

This trait can be used with an abstract Pet class to create a Dog:

abstract class Pet (var name: String) {
  def speak  // abstract
  def ownerIsHome { println("excited") }
}

class Dog (name: String) extends Pet (name) with Tail {
  def speak { println("woof") }
}

A Dog can now use the methods defined by both the abstract Pet class, as well as the Tail trait:

object Test extends App {
  val zeus = new Dog("Zeus")
  zeus.ownerIsHome
  zeus.wagTail
  zeus.speak
}

Limiting which classes can use a trait

You can limit a trait so it can only be added to classes which extend a specific subclass. To do this, use the “trait [TraitName] extends [SubclassName]” syntax. For instance, in the following example the Starship and WarpCore both extend the common superclass StarfleetComponent, so the WarpCore trait can be mixed into the Starship class:

class StarfleetComponent
trait WarpCore extends StarfleetComponent
class Starship extends StarfleetComponent with WarpCore

However, in the following example, the Warbird can’t extend the WarpCore trait because Warbird and WarpCore don’t share the same superclass:

class StarfleetComponent
trait WarpCore extends StarfleetComponent
class RomulanStuff
class Warbird extends RomulanStuff with WarpCore   // won't compile

A trait inheriting a class is not a common occurrence, and in general the following approach is preferred.

You can mark your traits so they can only be used by subclasses of a certain type. To do this, begin your trait with the “this: LimitingType =>” statement, as shown here:

trait MyTrait {
  this: LimitingType =>
  // more code here ...

For instance, to make sure a WarpCore can only be used in a Starship, mark the WarpCore trait like this:

trait WarpCore {
  this: Starship =>
}

Now this code will work:

class Starship
class Enterprise extends Starship with WarpCore

But other attempts like this will fail:

class RomulanShip
class Warbird extends RomulanShip with WarpCore   // this won't compile

Adding a trait to an object instance

This next example shows that you can add a trait to an instance of a class (an object):

class DavidBanner

trait Angry {
  println("You won't like me ...")
}

object Test extends App {
  val hulk = new DavidBanner with Angry
}

Extending Java interfaces like Scala traits

You can extend Java interfaces like Scala traits. In your Scala application, just use the extends and with keywords to implement your Java interfaces:

// java
public interface Animal {
  public void speak();
}

public interface Wagging {
  public void wag();
}

public interface Running {
  public void run();
}

// scala
class Dog extends Animal with Wagging with Running {
  def speak { println("Woof") }
  def wag { println("Tail is wagging!") }
  def run { println("I'm running!") }
}

Summary

I hope these Scala trait examples have been helpful. I’ll try to keep adding more to these examples as time goes on.