How to use abstract and concrete fields in Scala traits

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is a very short recipe, Recipe 8.2, “How to use abstract and concrete fields in Scala traits.”

Problem

You want to put abstract or concrete fields in your Scala traits so they are declared in one place and available to all types that implement the trait.

Solution

Define a field with an initial value to make it concrete; otherwise, don’t assign it an initial value to make it abstract. This trait shows several examples of abstract and concrete fields with var and val types:

trait PizzaTrait {
    var numToppings: Int     // abstract
    var size = 14            // concrete
    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 following Pizza class demonstrates how to set the values for the numToppings and size fields in a concrete class:

class Pizza extends PizzaTrait {
    var numToppings = 0      // 'override' not needed
    size = 16                // 'var' and 'override' not needed
}

Discussion

As shown in the example, fields of a trait can be declared as either var or val. You don’t need to use the override keyword to override a var field in a subclass (or trait), but you do need to use it to override a val field:

trait PizzaTrait {
    val maxNumToppings: Int
}

class Pizza extends PizzaTrait {
    override val maxNumToppings = 10  // 'override' is required
}

Overriding var and val fields is discussed more in Recipe 4.13, “Defining Properties in an Abstract Base Class (or Trait)”.