abstract class

What def, val, and var fields in Scala traits look like after they’re compiled (including the classes that extend them)

Table of Contents1 - def field in trait2 - val field in trait (abstract)3 - val field in trait (concrete)4 - var field in trait (abstract)5 - var field in trait (concrete)6 - An abstract class in the middle7 - A trait in the middle8 - Summary

I generally have a pretty good feel for how Scala traits work, and how they can be used for different needs. As one example, a few years ago I learned that it’s best to define abstract fields in traits using def. But there are still a few things I wonder about.

Today I had a few free moments and I decided to look at what happens under the covers when you use def, val, and var fields in traits, and then mix-in or extend those traits with classes. So I created some examples, compiled them with scalac -Xprint:all, and then decompiled them with JAD to see what everything looks like under the covers.

I was initially going to write a summary here, but if you want to know how things work under the hood, I think it helps to work through the examples, so for today I’ll leave that as an exercise for the reader.

A good reason to use sealed traits and classes in Scala

This scala-lang.org documentation page shares a good reason to use “sealed” traits and classes: When you created sealed traits, the compiler can easily tell all of the subtypes of your class or trait, and as just one benefit, you don’t need to add a default, “catch-all” case in your Scala match expressions.

How to use a Scala trait like an abstract class

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 8.3, “How to use a Scala trait like an abstract class.”

Problem

You want to use a trait as something like an abstract class in Java.

Solution

Define methods in your trait just like regular Scala methods. In the class that extends the trait, you can override those methods or use them as they are defined in the trait.

How to use a Scala trait as an interface (like a Java interface)

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 8.1, “How to use a Scala trait as an interface.”

Problem

You’re used to creating interfaces in other languages like Java and want to create something like that in Scala.

Solution

You can use a Scala trait just like a Java interface. As with interfaces, just declare the methods in your trait that you want extending classes to implement:

Scala: How to define properties in an abstract base class or trait

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.13, “How to define properties in an abstract base class or trait.”

Problem

You want to define abstract or concrete properties in an abstract base class (or trait) that can be referenced in all child classes.

When to use an abstract class in Scala (instead of a trait)

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.12, “When to use an abstract class in Scala.”

Problem

Scala has traits, and a trait is more flexible than an abstract class, so you wonder, “When should I use an abstract class?”

Solution

There are two main reasons to use an abstract class in Scala:

A Java “Extract Interface” refactoring example

Java Refactoring FAQ: Can you provide an example of the Extract Interface refactoring process?

While working on a Java Swing development project recently, I had written a couple of controllers (as in controllers from the Model/View/Controller pattern), and I was about to write some more, when I realized that if I refactored my Java source code I would have a much better design -- source code I code more easily maintain.

The pattern I saw repeated in my Java controller classes was that they all had similar method names, something like this: