Scala - 特質Trait

特質Trait

在scala中,有一個既相似java接口的又相似java抽象類的概念,叫作特質Trait。
咱們能夠把他看成接口來用,使用方式和java的接口相似,也能夠把他看成抽象類使用,使用方式就和java的抽象類相似。可是無論用接口仍是抽象的方式,都是使用關鍵字extends
接口的方式:java

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

抽象類的方式:ide

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的方法實現。scala

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。code

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

打印結果以下:it

ScalaTraitD03
ScalaTraitD02
ScalaTraitD01
相關文章
相關標籤/搜索