Scala 速通语法(七)| 特质

特质


  • 特质 (Traits) 用于在类 (Class)之间共享程序接口 (Interface)和字段 (Fields)。 它们类似于Java 8的接口。 类和对象 (Objects)可以扩展特质,但是特质不能被实例化,因此特质没有参数。

  • 定义一个特质
  //最简化的特质就是关键字trait+标识符:
    trait HairColor
  //特质作为泛型类型和抽象方法非常有用
    trait Iterator[A] {
      def hasNext: Boolean
      def next(): A
    }
  //扩展 trait Iterator [A] 需要一个类型 A 和实现方法hasNext和next

  //实现
  class Test extends HairColor{
    override def hasBext : Boolean = true
    override def next():String ={println("test trait")}
  }
  • Trait 的使用
    • 一个类具有某种特质,就意味着这个类满足了这个特制的所有要素,使用时采用extends关键字,如果多个特质,那么需要使用with连接
    • 没有父类
      class 类名 extends 特质1 with 特质2 with 特质3
    • 有父类
      class 类名 extends 父类 with 特质1 with 特质2 with 特质3

  • Trait中定义字段和方法
    在Trait中定义字段 必须在继承类中具体实现(不需要override关键字) 除了继承类为abstract class不需要实现
    特质可以同时拥有抽象方法和具体方法,一个类可以实现/继承多个特质
    所有的 java 接口都可以当做 Scala 特质使用

  • Trait动态混入
  1. 动态混入特质 扩展目标类的功能
  2. 此种方式也可以应用于对抽象类功能进行扩展
  3. 动态混入是Scala特有的方式,可以在不修改类声明、定义的前提下,扩展类的功能
  4. 可以在不改变类继承关系的前提下,扩展类的功能
  5. 同时要注意动态混入时,如果抽象类有抽象方法如何混入
//动态混入
package com.zhy.charter03

/**
 * @author ZHY
 * @data 2021/9/20
 */
object MaxInDeno01 {
  def main(args: Array[String]): Unit = {
    //在不修改 类的定义基础继承关系,让他们可以使用 trait 方法
    val oracleDB =new OracleDB with t3
    oracleDB.insert(100)

    val mySQL3 = new MySQL3 with t3
    mySQL3.insert(2020)

    //抽象类有抽象方法,动态混入特质
    val mySQL3_ = new MySQL3_ with t3 {
      override def say(): Unit = {
        println("say 抽象类实现")
      }
    }
    mySQL3_.say()
  }
}
trait t3{
  def insert(id:Int): Unit ={//方法 特质实现
    println("插入--->"+id)
  }
}
class OracleDB{//空
}
abstract class MySQL3{//空
}
abstract class MySQL3_{
  def say()
}
  • 叠加特质
  1. 构建对象的同时如果混入多个特质,称之为叠加特质,那么特质声明顺序从左到右,方法执行顺序从右到左(类似压栈出栈)

特质声明顺序从左到右
Scala 在执行叠加对象的方法时,会首先从后面的特质(从右向左)开始执行
Scala 中特质中如果调用 super,并不是表示调用父特质的方法,而是向前面(左边)继续查找特质,如果找不到,才会去父特质查找
如果想要调用具体特质的方法,可以指定:super[特质].xxx(…).其中的泛型必须是该特质的直接超类类型


  1. Scala中类只能继承一个超类, 可以扩展任意数量的特质
  2. 特质可以要求实现它们的类具备特定的字段, 方法和超类
  3. Scala特质可以提供方法和字段的实现 既有非抽象方法也有抽象方法的特质叫做富接口
  4. 当将多个特质叠加使用的时候, 顺序很重要(会影响特质调用父类类特质的方法 -> super.xxx())
上一篇:Scala 速通语法(八)| 隐式转换


下一篇:scala reduce 图解