Multiple inheritance is not allowed in Java/C# and the only other way to build common functionality among a set of related classes is via interfaces. But interfaces are abstract and require concrete implementation. The other option is to create a class that implements the desired interfaces and then inherit from that class. This is not very convenient.
Following are some of the cool features of a trait:
- A Trait is much like an abstract class in C#. It can contain abstract members as well as concrete implementations
- A Trait can contain abstract fields as well as concrete fields
- A class in Scala can only have one base class but it can implement any number of Traits. So a lot of concrete implementations are readily available for use.
- A Trait can extend other Traits.
- A Trait can extend other classes
- An instance of a class can implement a Trait. So, not the class, but the desired instances of that class can implement Traits as needed.
An abstract Trait called Runner that has an abstract method called Run
trait Runner
{
def Run(destination:String) //a string input param called "destination"
}
A class called Athlete that provides the implementation for the Trait:
class Athlete extends Runner
{
//override keyword is not necessary while implementing an abstract method of a trait
def Run(destination:string) {println(destination)}
}
A concrete Trait called Runner that has a concrete method called Run
trait Runner
{
def Run(destination:String) //a string input param called "destination"
{
println(destination)
}
}
A class called Athlete that implements the Trait and calls the Run method. In Scala slang "The Runner functionality is mixed in with the Athlete class"
class Athlete extends Runner
{
def PrintDestination(destination:String)
{
Run(destination);
}
}
A trait called MarathonRunner that extends the trait Runner
trait MarathonRunner extends Runner
{
def PrintMarathonDestination(destination:String)
{
Run(destination)
}
}
A class called Athlete that implements both Runner and MarathonRunner
class Athlete extends Runner with MarathonRunner
{
}
NOTE : In Scala, the first trait is implemented using the extends keyword and the second trait is implemented using the with keyword
Let us say that there is a trait called HalfMarathonRunner, an instance of the class Athlete can implement this trait:
val objAthlete = new Athlete with HalfMarathonRunner
A trait with an abstract field
trait Runner
{
val MaxDistance:int //no initial value means abstract
}
a trait with a concrete field
trait Runner
{
val MaxDistance = 15
}