Traits: Using Traits As Interfaces (Scala 3 Video)
At their most basic level, traits can be used as simple interfaces. Like classes, traits can contain members, which are methods and fields. Members can be:
- Abstract
- Concrete
In this lesson we’ll just look at abstract members, and see how to use those as we “mix them” into classes, which will provide implementations for them.
Members are public by default --- publicly accessible --- and we’ll use them that way in this lesson.
Example of traits as interfaces
trait HasTail:
def startTail(): Unit
def stopTail(): Unit
trait CanSpeak:
def speak(): Unit
class Dog extends HasTail, CanSpeak:
def startTail(): Unit = println("Tail is wagging")
def stopTail(): Unit = println("Tail is stopped")
def speak(): Unit = println("Woof")
val d = Dog()
d.speak()
d.startTail()
d.stopTail()
One benefit of traits as interfaces
Could write this to take a Dog
, but it’s more flexible to just accept the CanSpeak
type:
def saySomething(speaker: CanSpeak) = speaker.speak()
For instance, now if you also have a Cat
:
class Cat extends CanSpeak:
def speak(): Unit = println("Meow")
you can do this:
saySomething(Dog())
saySomething(Cat())
Extracting interfaces from classes
You can also work the other way around. You might first create a Dog
class:
class Dog:
def startTail = println("Tail is wagging")
def stopTail = println("Tail is stopped")
def speak = println("Woof")
And then a Cat
class:
class Dog:
def startTail = println("Tail is wagging")
def stopTail = println("Tail is stopped")
def speak = println("Meow")
And then you would see the common functionality between Dog
and Cat
, and extract the HasTail
and CanSpeak
interfaces, ending up at the same solution.
Update: All of my new videos are now on
LearnScala.dev