特质
- 特质 (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动态混入
- 动态混入特质 扩展目标类的功能
- 此种方式也可以应用于对抽象类功能进行扩展
- 动态混入是Scala特有的方式,可以在不修改类声明、定义的前提下,扩展类的功能
- 可以在不改变类继承关系的前提下,扩展类的功能
- 同时要注意动态混入时,如果抽象类有抽象方法如何混入
//动态混入
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()
}
- 叠加特质
- 构建对象的同时如果混入多个特质,称之为叠加特质,那么特质声明顺序从左到右,方法执行顺序从右到左(类似压栈出栈)
特质声明顺序从左到右
Scala 在执行叠加对象的方法时,会首先从后面的特质(从右向左)开始执行
Scala 中特质中如果调用 super,并不是表示调用父特质的方法,而是向前面(左边)继续查找特质,如果找不到,才会去父特质查找
如果想要调用具体特质的方法,可以指定:super[特质].xxx(…).其中的泛型必须是该特质的直接超类类型
- Scala中类只能继承一个超类, 可以扩展任意数量的特质
- 特质可以要求实现它们的类具备特定的字段, 方法和超类
- Scala特质可以提供方法和字段的实现 既有非抽象方法也有抽象方法的特质叫做
富接口
- 当将多个特质叠加使用的时候, 顺序很重要(会影响特质调用父类类特质的方法 -> super.xxx())