Self types allow us to easily separate code in our applications, and then require it from other places. Everything gets clearer with an example, so let's have a look at one. Let's assume that we want to be able to persist information into a database:
trait Persister[T] { def persist(data: T)}
The persist method will do some transformations on the data and then insert it in our database. Of course, our code is well-written, so the database implementations are separated. We have the following for our database:
import scala.collection.mutabletrait Database[T] { def save(data: T)}trait MemoryDatabase[T] extends Database[T] { val db: mutable.MutableList[T] = mutable.MutableList.empty override def save(data: T): Unit = { System.out.println("Saving ...