Scala Traits
A trait is a list of promises that a class keeps. A class that takes a trait must supply the promised methods, and it can also use ready-made methods the trait already holds.
A class keeps a trait promise
The Greeter trait promises a greet method with no body. The Host class supplies the method and marks it with override.
trait Greeter:
def greet(): String
class Host(name: String) extends Greeter:
override def greet(): String = s"Hello from $name"
@main def main(): Unit =
val ana = Host("Ana")
println(ana.greet())Classes share a ready-made method
The Friendly trait holds a hello method with a body. Both classes take the trait and use the same method.
trait Friendly:
def hello: String = "Hello!"
class Dog(val name: String) extends Friendly
class Cat(val name: String) extends Friendly
@main def main(): Unit =
val rex = Dog("Rex")
val tom = Cat("Tom")
println(rex.hello)
println(tom.hello)
println(rex.name)A trait can mix a promise and a body
The Player trait promises a team and builds a badge line from it. The Striker class supplies the team, and the badge works at once.
trait Player:
def team: String
def badge: String = s"Player of $team"
class Striker(val name: String) extends Player:
override def team: String = "Reds"
@main def main(): Unit =
val sam = Striker("Sam")
println(sam.badge)
println(sam.team)
println(sam.name)Example
trait Worker:
def job: String
def intro: String = s"I work as a $job"
class Cook(val name: String) extends Worker:
override def job: String = "cook"
@main def main(): Unit =
val mia = Cook("Mia")
println(mia.intro)
println(mia.job)
println(mia.name)Key points
- Trait: a list of promises and ready-made methods that a class can take.
- Promise: a def in a trait with no body, which names work a class must supply.
- Ready-made method: a def in a trait with a body, which classes taking the trait share as it is.
- Extends: a class takes a trait with the word extends, the same word used for a parent class.
- Override: a class marks a supplied promise with the word override.
- Sharing: many different classes can take the same trait and use its ready-made methods.
In this example, the Worker trait promises a job method and holds a ready-made intro method that uses it. The Cook class supplies the job with override, so intro can build its line. The prints show the intro line, the job itself, and the name field of the cook.
Note
a trait is not a class, so a program cannot create a value directly from a trait.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What must a class do for a trait method that has no body?