Contact Us

Use the form on the right to contact us.

           

123 Street Avenue, City Town, 99999

(123) 555-6789

email@address.com

 

You can set your address, phone number, email and site description in the settings tab.
Link to read me page with more information.

Blog

Scala: Traits and Self Types

Mark Thomas

Scala has a few features that, for those who come from a Java or C# background, provide new ways of modelling components and services. I'm going to write a few posts on this, but begin by describing some of the language features that enable them. First up is traits.

What is a trait?

A trait is a collection of fields and methods. Traits can be mixed in to classes to add new features or to modify behaviour. Scala's Ordered trait is a good example of this:

trait Ordered[A] {
  def compare(that: A): Int

  def <  (that: A): Boolean = (this compare that) <  0
  def >  (that: A): Boolean = (this compare that) >  0
  def <= (that: A): Boolean = (this compare that) <= 0
  def >= (that: A): Boolean = (this compare that) >= 0
  def compareTo(that: A): Int = compare(that)
}

By mixing-in Ordered to a new class, then you can get four useful operators by just implementing compare. This is quite powerful, for example:

class Money extends Ordered[Money] with SomeOtherTrait {
  ...

  def compare(that: Money) = {
    ...
  }

As classes can be composed of many traits, this creates a powerful way of building richer classes from simpler ones by layering in capabilities.

Self Types

Ordered can be mixed in to any class; it doesn't depend on any methods or fields of the class that it is mixed in to. Sometimes it's useful for a trait to be able to use the fields or methods of a class it is mixed in to, this can be done by specifying a self type for the trait. A self type can be specified for a class or a trait as follows:

trait SpellChecker { self =>
  ...
}

self within the context of this trait will refer to this. Aliasing this is useful for nested classes or traits where it would otherwise be difficult to access a particular this. The syntax can be extended to specify a lower-bounds on this, when this is done the trait or class can use the features of this lower-bound class, so it can extend or modify its behaviour.

trait SpellChecker { self: RandomAccessSeq[char] =>
  ...
}

The compiler will check that any class in a hierarchy including SpellChecker is or extends RandomAccessSeq[char], so SpellChecker can now use the fields or methods of RandomAccessSeq[char]