特质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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。