关于scala:Scala-特质Trait

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理