Trait
In scala, there is a concept that is similar to Java interface and Java abstract class, called Trait.
We can use it as an interface, and its usage is similar to that of Java's interface, or it can be used as an abstract class, and its usage is similar to that of Java's abstract class. But regardless of the interface or abstract method, the keyword extends
is used.
The way of the interface:
trait ScalaTrait {
def printInfo(): Unit
}
class ScalaClass extends ScalaTrait {
override def printInfo(): Unit = {
println("ScalaClass")
}
}
object ScalaClass {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass
scalaClass.printInfo()
}
}
The way of abstract class:
trait ScalaTrait2 {
def printInfo(): Unit
def printInfo2(): Unit = println("printInfo2")
}
class ScalaClass2 extends ScalaTrait2 {
override def printInfo(): Unit = {
println("ScalaClass2")
}
}
object ScalaClass2 {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass2
scalaClass.printInfo()
scalaClass.printInfo2()
}
}
Multiple Trait inheritance
Abstract classes cannot be multiple inherited, but traits can be multiple inherited, multiple traits directly use the with keyword.
In the following example, ScalaClass3 has both the method implementation of ScalaTraitA01 and the method implementation of ScalaTraitA02.
trait ScalaTraitA01 {
def printInfo01(): Unit
}
trait ScalaTraitA02 {
def printInfo02(): Unit
}
class ScalaClass3 extends ScalaTraitA01 with ScalaTraitA02 {
def printInfo01(): Unit = {
println(s"printInfo01")
}
def printInfo02(): Unit = {
println(s"printInfo02")
}
}
object ScalaClass3 {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass3
scalaClass.printInfo01()
scalaClass.printInfo02()
}
}
Duplicate attributes
For example, multiple traits inherited have a certain attribute, and when you call, you don't know which attribute is called. At this time, you need to rewrite this value by subclasses. For example, str is defined as ScalaClass4 by override.
trait ScalaTraitB01 {
val str: String = "strB01"
def printInfo01(): Unit
}
trait ScalaTraitB02 {
val str: String = "strB02"
def printInfo02(): Unit = println("printInfo02 " + str)
}
class ScalaClass4 extends ScalaTraitB01 with ScalaTraitB02 {
override val str: String = "ScalaClass4"
override def printInfo01(): Unit = {
println(str)
}
}
object ScalaClass4 {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass4
scalaClass.printInfo01()
scalaClass.printInfo02()
}
}
Repeat method
Both ScalaTraitC01 and ScalaTraitC02 have the printInfo01 method. The subclass calls super.printInfo01(), and the result shows that the method in ScalaTraitC02 is called.
In the Trait call chain, it is called from the far right to the left of with.
trait ScalaTraitC01 {
val str: String = "strC01"
def printInfo01(): Unit = println("printInfoC01 " + str)
}
trait ScalaTraitC02 {
val str: String = "strC02"
def printInfo01(): Unit = println("printInfoC02 " + str)
}
class ScalaClass5 extends ScalaTraitC01 with ScalaTraitC02 {
override val str: String = "ScalaClass5"
override def printInfo01(): Unit = {
super.printInfo01()
}
}
object ScalaClass5 {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass5
scalaClass.printInfo01()
}
}
We can implement the chain of responsibility model through this feature:
trait ScalaTraitD00 {
def printInfo01(): Unit = {}
}
trait ScalaTraitD01 extends ScalaTraitD00 {
override def printInfo01(): Unit = {
println("ScalaTraitD01")
super.printInfo01()
}
}
trait ScalaTraitD02 extends ScalaTraitD00 {
override def printInfo01(): Unit = {
println("ScalaTraitD02")
super.printInfo01()
}
}
trait ScalaTraitD03 extends ScalaTraitD00 {
override def printInfo01(): Unit = {
println("ScalaTraitD03")
super.printInfo01()
}
}
class ScalaClass6 extends ScalaTraitD01 with ScalaTraitD02 with ScalaTraitD03 {
override def printInfo01(): Unit = {
super.printInfo01()
}
}
object ScalaClass6 {
def main(args: Array[String]): Unit = {
val scalaClass = new ScalaClass6
scalaClass.printInfo01()
}
}
The print result is as follows:
ScalaTraitD03
ScalaTraitD02
ScalaTraitD01
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。