特质 Trait
在 scala 中,有一个既相似 java 接口的又相似 java 抽象类的概念,叫做特质 Trait。
咱们能够把他当作接口来用,应用形式和 java 的接口相似,也能够把他当作抽象类应用,应用形式就和 java 的抽象类相似。然而不论用接口还是形象的形式,都是应用关键字 extends
。
接口的形式:
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()}
}
抽象类的形式:
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()}
}
多个 Trait 继承
抽象类是不能多继承的,然而 Trait 是能够多继承的,多个 Trait 间接用 with 关键字。
上面例子中,ScalaClass3 既有 ScalaTraitA01 的办法实现,也有 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()}
}
反复属性
比方继承的多个 Trait 都有某个属性,那调用的时候,就不晓得是调用哪个属性,此时就须要子类去重写这个值,比方 str 通过 override 重写定义为 ScalaClass4。
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()}
}
反复办法
ScalaTraitC01 和 ScalaTraitC02 都有 printInfo01 办法,子类调用 super.printInfo01(),结果显示调用的是 ScalaTraitC02 里的办法。
在 Trait 调用链中,是从 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()}
}
咱们能够通过这个个性实现责任链模式:
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()}
}
打印后果如下:
ScalaTraitD03
ScalaTraitD02
ScalaTraitD01