Traits as Interfaces
Let’s start with something familiar. A Scala trait can work exactly like a Java interface. For example:
trait Logger { def log(msg: String) // An abstract method}
A subclass can provide an implementation:
class ConsoleLogger extends Logger { // Use extends, not implements def log(msg: String) { println(msg) } // No override needed}
If you need more than one trait, add the others using the with keyword: All Java interfaces can be used as Scala traits.
class ConsoleLogger extends Logger with Cloneable with Serializable
Traits with def, val and var
Never use val
in a trait
for abstract members and use def
instead. .
Traits with Concrete Implementations
In Scala, the methods of a trait need not be abstract.
trait ConsoleLogger {def log(msg: String) { println(msg) }}
Here is an example of using this trait:
class SavingsAccount extends Account with ConsoleLogger {def withdraw(amount: Double) {if (amount > balance) log("Insufficient funds")else balance -= amount}...}
Note the difference between Scala and Java. The SavingsAccount picks up a concrete implementation from the ConsoleLogger trait. This would not be possible with a Java interface.
Objects with Traits
You can add a trait to an individual object when you construct it.
trait Logged {def log(msg: String) { }//do nothing implementation}