继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Scala(六)-①-面相对象高级-特质(下)-嵌套类-隐式转换和隐式参数-隐式类

慕虎7371278
关注TA
已关注
手记 1267
粉丝 203
获赞 873

① 特质(下)

在上一篇博文中,我已经介绍了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


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP