Scala-特質Trait

4041 ワード

特質トラック
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キーワードを直接使用します.以下の例では、ScalaClass 3は、ScalaTraitA 01のメソッド実装と、ScalaTraitA 02のメソッド実装とがある.
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でScalaClass 4として定義されているなど、サブクラスがこの値を書き換える必要があります.
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()
  }
}

繰返し方法
ScalaTraitC 01とScalaTraitC 02にはprintInfo 01メソッドがあり、サブクラスはsuper.printInfo 01()を呼び出し、結果としてScalaTraitC 02のメソッドが呼び出されていることを示します.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