特质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