Scala 特质 内容整理

1.特质中可以加入抽象方法和具体方法,可以直接当作Java下的接口使用。

2.类可以直接添加特质,使用extends关键字,多个特质使用with相连

trait Logger{
  def log(msg:String)
}
class ConsoleLogger extends Logger{
  def log(msg:String){println(msg)}
}

3.定义对象时可以直接动态混入特质。(使用with关键字)

trait Logger{
  def log(msg:String,key:Int=3)
}
class A{
  
}
val a:A=new A with Logger {
  override def log(msg: String, key: Int): Unit = ???
}

4.特质的叠加(难点!)

构建对象的同时如果混入多个特质,称之为叠加特质。

特质的声明顺序从左到右 ,方法执行顺序从右到左。

package com.atguigu.chapter08.mixin

//看看混入多个特质的特点(叠加特质)
object AddTraits {
  def main(args: Array[String]): Unit = {

    //说明
    //1. 创建 MySQL4实例时,动态的混入 DB4 和 File4

    //研究第一个问题,当我们创建一个动态混入对象时,其顺序是怎样的
    //总结一句话
    //Scala在叠加特质的时候,会首先从后面的特质开始执行(即从左到右)
    //1.Operate4...
    //2.Data4
    //3.DB4
    //4.File4
    val mysql = new MySQL4 with DB4 with File4
    println(mysql)

    //研究第2个问题,当我们执行一个动态混入对象的方法,其执行顺序是怎样的
    //顺序是,(1)从右到左开始执行 , (2)当执行到super时,是指的左边的特质 (3) 如果左边没有特质了,则super就是父特质
    //1. 向文件"
    //2. 向数据库
    //3. 插入数据 100
    mysql.insert(100)

    println("===================================================")
    //练习题
    val mySQL4 = new MySQL4 with  File4 with DB4
    mySQL4.insert(999)
    //构建顺序
    //1.Operate4...
    //2.Data4
    //3.File4
    //4.DB4

    //执行顺序
    //1. 向数据库
    //2. 向文件
    //3. 插入数据 = 999
  }
}

trait Operate4 { //特点
  println("Operate4...")

  def insert(id: Int) //抽象方法
}

trait Data4 extends Operate4 { //特质,继承了Operate4
  println("Data4")

  override def insert(id: Int): Unit = { //实现/重写 Operate4 的insert
    println("插入数据 = " + id)
  }
}

trait DB4 extends Data4 { //特质,继承 Data4
  println("DB4")

  override def insert(id: Int): Unit = { // 重写 Data4 的insert
    println("向数据库")
    super.insert(id)
  }
}

trait File4 extends Data4 { //特质,继承 Data4
  println("File4")

  override def insert(id: Int): Unit = { // 重写 Data4 的insert
    println("向文件")
    //super.insert(id) //调用了insert方法(难点),这里super在动态混入时,不一定是父类
    //如果我们希望直接调用Data4的insert方法,可以指定,如下
    //说明:super[?] ?的类型,必须是当前的特质的直接父特质(超类)
    super[Data4].insert(id)
  }
}

class MySQL4  {} //普通类



5.特质中重写抽象方法

如果超类特质的方法是抽象的,不能在子类中写super.超类抽象方法,很好理解,但在方法前加入关键字abstract override便可以正常使用。

6.富接口:带有抽象方法和具体方法的特质

7.特质中的字段:可以有具体的,也可以有抽象的,但抽象的在混入时需要实现。

8.特质的构造顺序:

1)声明类的同时混入特质

     1.调用当前类的超类构造器;2.第一个特质的父构造器;3.第一个特质的构造器;4.第二个特质构造器的父特质构造器,如果已经执行过,就不再执行;5.第二个特质构造器;6.重复4,5步骤(如果有第3个,第4个特质);7.当前类构造器

2)构建对象时动态混入特质

     1.调用当前类的超类构造器;2.当前类构造器;3第一个特质构造器的父特质构造器;4.第一个特质构造器;5.第二个特质构造器的父特质构造器, 如果已经执行过,就不再执行 6.第二个特质构造器;7........重复5,6的步骤(如果有第3个,第4个特质);8.当前类构造器

9.拓展类的特质

特质可以继承类,以用来拓展该特质的一些功能。

所有混入该特质的类,会自动成为哪个特质所继承的超类的子类。

如果混入该特质的类,已经继承了另一个类(A类),则要求A类时特质超类的子类,否则就会出现了多继承现象,发生错误。

10.自身类型。

1)不拓展类的情况下,限制混入该特质类的类型

2)可以使用类中的方法

package com.atguigu.chapter08.selftype

object SelfTypeDemo {
  def main(args: Array[String]): Unit = {



  }
}

//Logger就是自身类型特质,当这里做了自身类型后,那么
// trait Logger extends Exception,要求混入该特质的类也是 Exception子类
trait Logger {
  // 明确告诉编译器,我就是Exception,如果没有这句话,下面的getMessage不能调用
  this: Exception =>
  def log(): Unit ={
    // 既然我就是Exception, 那么就可以调用其中的方法
    println(getMessage)
  }
}

//class Console extends  Logger {} //对吗? 错误
class Console extends Exception with Logger {}//对吗?

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值