In real applications, we might require more than one component using a self type. Let's show this in our example with a History trait that could potentially keep track of changes to roll back at some point. Ours will just do printing:
trait History { def add(): Unit = { System.out.println("Action added to history.") }}
We need to use this in our Persister trait, and it will look like this:
trait Persister[T] { this: Database[T] with History => def persist(data: T): Unit = { System.out.println("Calling persist.") save(data) add() }}
Using the with keyword, we can add as many requirements as we like. However, if we just leave our code changes there, it will not compile. The reason for this is that we must now mix ...