8.2. Using Abstract and Concrete Fields in Traits

Problem

You want to put abstract or concrete fields in your 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.

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.