1. Overview

In this tutorial, we’ll see what abstract classes and traits are in Scala and the key differences between them.

Scala provides both of these mechanisms to enable behavior reuse across different classes through inheritance. Let’s see in further detail how they can help on that task.

2. Abstract Classes

Abstract classes in Scala are very similar to what we have in Java. In fact, Scala abstract classes are fully interoperable with Java. This is especially useful in codebases that use both languages. It means we can call the Scala abstract classes and subclasses from Java without needing any kind of workaround.

Abstract classes are more indicated for refining what an object is. For instance, we can have an abstract class Animal and now say that Cow is a subclass of Animal. One important limitation is that classes can only inherit from a single abstract class at most.

Abstract classes are defined with the abstract modifier preceding the class keyword. Moreover**,** abstract classes can contain fully defined methods and abstract methods as well:

abstract class Animal {

  def heartBeat(): Int = {
    42
  }

  // this is an abstract method that should 
  // be overridden by subclasses
  def eat(): String // returns the sound made while eating
}

3. Traits

Just like abstract classes, traits are an inheritance mechanism to allow reusing behavior across different classes. One of the most important features of traits is that a class may inherit from multiple traits.

While developers tend to compare them to java interfaces*,* they are not quite the same in Scala as we shall see. And if we tried to use a Scala trait from Java code, we’d find the need for some minor workarounds.

Traits are used to group methods for a given behavior. Just like abstract classes they can have fully defined and not implement methods. Traits are defined using the trait keyword:

trait Walker {
  def walk(): Int // returns the number of steps walked
  
  def rest(): Int = {
    0
  }
}

4. Significant Differences

There are many differences between abstract classes and traits. In this article, we are focusing on the most important. For a full understanding, we should look into the language specification, as well as into the underlying JVM specification.

The first difference was already mentioned: classes are limited to inherit from a single abstract class but can inherit from multiple traits.

Another important difference is that abstract classes allow specifying constructor parameters. Traits do not allow us to do the same. Nevertheless, both approaches allow specifying type parameters.

Some guidelines to decide when to use abstract classes or traits:

  • If it might be reused in several and unrelated classes, we should implement it as a trait. In complex class hierarchies mixing a trait is possible, but adding an abstract class in between won’t be possible
  • If we still do not know, after considering the above, then let’s start by making it a trait. We can always change it later, and in general, using a trait keeps more options open

5. Conclusion

In this article, we saw two approaches to re-use behavior using inheritance in Scala: abstract classes and traits. We checked how to use each of them and navigated through their main differences.