We continue with more Scala on the topic of Traits in this post. For
all the work in this post, we will use Read-Evaluate-Print-Loop
Scala interpreter. Some familiarity
with Java will be of great help in understanding Scala. In this post, we will
look at the way traits are declared and how traits are called in programs.
Traits can be seen as abstract classes in Scala. Like in Java, a concrete class that extends a trait must implement all methods in the trait definition. Like in Java, traits cannot be instantiated. An example can be seen below:
trait trait1 { def method1 }
trait trait2 { def method2 }
trait trait3 { def method3 }
class TraitImplementation extends trait1 with trait2 with trait3{
def method1 { println ("In method1") }
def method2 { println ("In method2") }
def method3 { println ("In method3") }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method1
TraitImplementation1.method2
TraitImplementation1.method3
The results are shown below:
scala> trait trait1 { def method1 }
defined trait trait1
scala> trait trait2 { def method2 }
defined trait trait2
scala> trait trait3 { def method3 }
defined trait trait3
scala> class TraitImplementation extends trait1 with trait2 with trait3{
| def method1 { println ("In method1") }
| def method2 { println ("In method2") }
| def method3 { println ("In method3") }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@6ee88e21
scala> TraitImplementation1.method1
In method1
scala> TraitImplementation1.method2
In method2
scala> TraitImplementation1.method3
In method3
Three traits are defined having a method definition each. The concrete class called TraitImplementation extends trait1 with keyword extends. But, for inheriting the next traits, we use the with keyword. The three methods are implemented in the class. After that, the class is instantiated, the three methods can be called.
If we try to instantiate a trait, we get below error:
scala> new trait1
<console>:13: error: trait trait1 is abstract; cannot be instantiated
new trait1
^
In case the member names are the same, then, the override keyword has to be used in the class extending the trait as shown below:
trait trait4 { def method4 { println("method4 in trait4") }}
class TraitImplementation extends trait4 {
override def method4 { println("method4 in TraitImplementation") }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method4
The results are shown below:
scala> trait trait4 { def method4 { println("method4 in trait4") }}
defined trait trait4
scala> class TraitImplementation extends trait4 {
| override def method4 { println("method4 in TraitImplementation") }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@2a136383
scala> TraitImplementation1.method4
method4 in TraitImplementation
As expected, the method overridden in the class is called. If, however, we need the method in the trait to be called, we have to use the super keyword as shown below:
trait trait5 { def method5 { println("method5 in trait5") }}
class TraitImplementation extends trait5 {
override def method5 { super[trait5].method5 }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method5
The results are shown below:
scala> trait trait5 { def method5 { println("method5 in trait5") }}
defined trait trait5
scala> class TraitImplementation extends trait5 {
| override def method5 { super[trait5].method5 }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@8f39224
scala> TraitImplementation1.method5
method5 in trait5
Now, the method in the parent trait is called.
This concludes the discussion on Traits in Scala.
Traits can be seen as abstract classes in Scala. Like in Java, a concrete class that extends a trait must implement all methods in the trait definition. Like in Java, traits cannot be instantiated. An example can be seen below:
trait trait1 { def method1 }
trait trait2 { def method2 }
trait trait3 { def method3 }
class TraitImplementation extends trait1 with trait2 with trait3{
def method1 { println ("In method1") }
def method2 { println ("In method2") }
def method3 { println ("In method3") }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method1
TraitImplementation1.method2
TraitImplementation1.method3
The results are shown below:
scala> trait trait1 { def method1 }
defined trait trait1
scala> trait trait2 { def method2 }
defined trait trait2
scala> trait trait3 { def method3 }
defined trait trait3
scala> class TraitImplementation extends trait1 with trait2 with trait3{
| def method1 { println ("In method1") }
| def method2 { println ("In method2") }
| def method3 { println ("In method3") }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@6ee88e21
scala> TraitImplementation1.method1
In method1
scala> TraitImplementation1.method2
In method2
scala> TraitImplementation1.method3
In method3
Three traits are defined having a method definition each. The concrete class called TraitImplementation extends trait1 with keyword extends. But, for inheriting the next traits, we use the with keyword. The three methods are implemented in the class. After that, the class is instantiated, the three methods can be called.
If we try to instantiate a trait, we get below error:
scala> new trait1
<console>:13: error: trait trait1 is abstract; cannot be instantiated
new trait1
^
In case the member names are the same, then, the override keyword has to be used in the class extending the trait as shown below:
trait trait4 { def method4 { println("method4 in trait4") }}
class TraitImplementation extends trait4 {
override def method4 { println("method4 in TraitImplementation") }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method4
The results are shown below:
scala> trait trait4 { def method4 { println("method4 in trait4") }}
defined trait trait4
scala> class TraitImplementation extends trait4 {
| override def method4 { println("method4 in TraitImplementation") }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@2a136383
scala> TraitImplementation1.method4
method4 in TraitImplementation
As expected, the method overridden in the class is called. If, however, we need the method in the trait to be called, we have to use the super keyword as shown below:
trait trait5 { def method5 { println("method5 in trait5") }}
class TraitImplementation extends trait5 {
override def method5 { super[trait5].method5 }
}
val TraitImplementation1 = new TraitImplementation
TraitImplementation1.method5
The results are shown below:
scala> trait trait5 { def method5 { println("method5 in trait5") }}
defined trait trait5
scala> class TraitImplementation extends trait5 {
| override def method5 { super[trait5].method5 }
| }
defined class TraitImplementation
scala> val TraitImplementation1 = new TraitImplementation
TraitImplementation1: TraitImplementation = TraitImplementation@8f39224
scala> TraitImplementation1.method5
method5 in trait5
Now, the method in the parent trait is called.
This concludes the discussion on Traits in Scala.