① 特质(下)
在上一篇博文中,我已经介绍了Scala中静态属性和方法之伴生对象实现,以及特质入门的一部分内容.该篇博文我将会介绍特质(下)、嵌套类、隐式(上).对于特质(下).我主要介绍以下主题, 叠加特质、自身类型、嵌套类
Why
叠加特质
为什么我们要学习叠加特质,这是因为Scala中并无多重继承,因为多重继承会带来很多问题, 为了能够实现多重继承又能规避其问题, Scala使得特质能够叠加,通俗说是让一个类能够具备多个特质.
自身类型(强制规定能够混入特质的类)
自身类型主要是为了解决特质的循环引入,即因为混入特质而形成的依赖回环.该技术
通过再特质中明确规定哪些类能够混入该特质来解决这个问题.
How
叠加特质
规则和语法
特质执行顺序由右向左.先执行File的insert方法,File中的super表示Trait1,所以会再执行Trait1的insert方法.
// 创建一个SomeObject对象,混入Trait1和Trait2特质val obj = new SomeObject with Trait1 with Trait2
叠加特质Demo
代码
object TraitDemo05MultiplyMixin { def main(args: Array[String]): Unit = { val mysql = new MySQL with DB with File
mysql.insert(100)
}
}class MySQL {}trait Operator { def insert(id :Int)
}trait Data extends Operator { override def insert(id: Int): Unit = {
println("插入数据")
}
}trait DB extends Data { override def insert(id: Int): Unit = {
println("向数据库插入数据") super.insert(id)
}
}trait File extends Data { override def insert(id: Int): Unit = {
println("向文件中插入数据") super.insert(id)
}
}输出
向文件中插入数据 向数据库插入数据 插入数据
特质构造由左到右,由父到子.由左到右构造特质,并且先构造父特质再构造子特质,如果父特质之前构造过则不再构造
顺序
object TraitDemo05MultiplyMixin02 { def main(args: Array[String]): Unit = { val mysql = new MySQL05 with DB05 with File05
}
}class MySQL05 {}trait Operator05 {
println("Operator")
}trait Data05 extends Operator05 {
println("Data")
}trait DB05 extends Data05 {
println("DB")
}trait File05 extends Data05 {
println("File")
}输出
Operator Data DB File
自身类型
代码
object TraitDemo09SelfTypeForCycleRefenrece { def main(args: Array[String]): Unit = {// val oracle = new Oracle09 with Logger // 错误
var mysql = new MySQL09 with Logger
}
}trait Logger { // 声明混入该特质的类必须是Exception或者其子类
this:Exception=> def log(): Unit = {
getMessage
}
}class Oracle09 {}class MySQL09 extends Exception {
}What
叠加特质
对象中混入特质原理见上篇.构建顺序和调用顺序原理就不再做细究.
Details
叠加特质
特质
声明顺序从左到右,构建顺序也是.Scala在
执行叠加对象的方法时,会首先从后面的特质(从右向左)开始执行Scala中特质中如果调用
super,并不是表示调用父特质的方法,而是向前面(左边)继续查找特质,如果找不到,才会去父特质查找如果想要
调用具体特质的方法,可以指定:super[特质].xxx(…).其中的泛型必须是该特质的直接超类类型富接口的概念: 具有
普通方法和抽象方法的特质的称呼特质中如果有抽象成员,无论字段或方法都需要混入的类来实现.
object TraitDemo06RichInterface { def main(args: Array[String]): Unit = { val mySQL = new MySQL06 with DBDriver06 { // 实现抽象字段
override var numberOfThread: Int = _ // 实现抽象方法
override def delete: Unit = {
}
}
}
}class MySQL06 { }trait DBDriver06 { var numberOfThread : Int
private var operatorType = "insert"
def insert(): Unit = {
} def delete}特质构造顺序之
声明时混入.声明时混入先构造子类,再从左到右够着特质(并且每构造特质之时先构造父特质),最后构造本类.
特质构造分两种,一种声明时混入,一种动态混入(new的时候混入).两种唯一的区别是,动态混入先构造本类,而声明时混入最后才构造本类,其它都一样.
代码
object TraitDemo07DecalreMixin { def main(args: Array[String]): Unit = {
println("声明时混入")
val ff = new FF
println("动态混入") // 动态混入
val ee = new EE with CC with DD
}
}trait AA {
println("A...")
}trait BB extends AA {
println("B....")
}trait CC extends BB {
println("C....")
}trait DD extends BB {
println("D....")
}class EE {
println("E...")
}// 声明时混入ee、cc、ddclass FF extends EE with CC with DD {
println("F....")
}// 声明时混入eeclass KK extends EE {
println("K....")
}
作者:sixleaves
链接:https://www.jianshu.com/p/5cea522b89a6
共同学习,写下你的评论
评论加载中...
作者其他优质文章