① 特质(下)
在上一篇博文中,我已经介绍了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
共同学习,写下你的评论
评论加载中...
作者其他优质文章