特质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()  }}

打印后果如下:

ScalaTraitD03ScalaTraitD02ScalaTraitD01