Hi community, in this blog we are gonna talk about the Traits and how Scala Traits can help you while performing multiple inheritances.
What are Traits?
Scala does not allow the concept of multiple inheritances for more than one class, so to do multiple inheritances Scala uses Traits
A trait is a fundamental unit of code reuse in Scala. A trait holds the definitions of method and field, which can be reused when mixing traits into classes. One thing to notice over here is that a class can be mixed with any number of traits which makes traits more powerful than class inheritance.
A simple definition of trait Printer
trait Printer {
def print(msg : String) = println (msg)
}
Mixing trait into a Class
Traits can be mixed with classes using extend keywords and hence the methods inherited from a trait can be used just like methods inherited from a superclass. Let’s see how this work
trait Printer {
def print(msg : String) = println(msg)
}
class CustomerPrint extends Printer {
override def print(msg: String): Unit ={
println("You have learned trait in this blog")
super.print(msg)
}
}
object Main{
def main(args: Array[String]): Unit = {
new CustomerPrint().print("End of your printing")
}
}
Output: You have learned trait in this blog
End of your printing
If you wish to mix a trait into a class that explicitly extends a super-class, you use extends to indicate the super-class and with to mix in the trait. For example
trait Printer {
def print(msg : String) = println(msg)
}
class Content{
def contentPrint(): Unit = {
println("Scala is a hybrid language")
}
}
class CustomerPrint extends Content with Printer {
override def print(msg: String): Unit ={
println("You have learned trait in this blog")
super.print(msg)
}
}
object Main{
def main(args: Array[String]): Unit = {
val finalPrint = new CustomerPrint
finalPrint.contentPrint()
finalPrint.print("End of your Printing")
}
}
Output: Scala is a hybrid language
You have learned trait in this blog
End of your Printing
Why not Multiple Inheritance?
As we all know that multiple inheritances are subject to the diamond problem. Diamond in computer science refers to the class inheritance diagram and it looks like this:
What’s the problem?
So we have four class A, B, C, and D from which A is a super-class, both B and C are child class which inherits from A and which is absolutely legal but when we go down to class D which inherits from child classes B and C which is not possible or it’s illegal and this is where the problem lies.
Let’s suppose that super-class A contains a method inside it and when our child classes(B & C) inherits from A they have the ability to override the method present inside A, but let’s just say that D tries to inherit from B & C and tries to override the method that is already overwritten in super-class A.
Hence the class D will get confused and it won’t know which method to override cause it might be the case that they’re pretty much the same method and also you can’t write two methods with the same name and this is what the Diamond problem is.
How to solve this problem?
Scala solves this problem with the help of Trait, as we already talked about above that Traits are more flexible than interfaces and can include methods too. Let’s take an example
trait Printer {
def print(msg : String) = println (msg)
}
trait PrintHyphen extends Printer {
override def print(msg : String) {
println("-------------")
super.print(msg)
}
}
trait PrintStar extends Printer {
override def print(msg : String) {
println("*************")
super.print(msg)
}
}
class Printing extends Printer with PrintHyphen with PrintStar
object CustomPrint {
def main(args: Array[String]): Unit = {
new Printing().print("Solving Diamond Problem")
}
}
Output: *************
-------------
Solving Diamond Problem
In the above code class Printing
is inheriting from both the traits PrintHyphen
and PrintStar
which in turn is inheriting from trait Printer
and also the output shows the order in which the methods are executed.
When super
is used to invoke methods in the above trait example linearization rule come into play to decide call hierarchy. Linearization order for Printing
will be:
Conclusion
Thank you guys for making it to the end of my blog, hoping that you must have gained slight knowledge of the Scala trait, how traits work and how to use them in several common idioms.
You saw that traits are similar to multiple inheritances, but because they interpret super using linearization, they both avoid some of the difficulties of traditional multiple inheritances and allow you to stack behaviors, in order to get more knowledge of Scala trait you can refer to the link given below.
References
https://www.artima.com/pins1ed/traits.html
https://docs.scala-lang.org/tour/traits.html
Your articles are pretty good, keep up the work.