Scala特质简介

从面向对象来看,接口并不属于面线对象的范畴,Scala是纯面向对象的语言,所以Scala中没有接口。为了弥补没有接口的缺点,开发者提出了trait 特质的概念。

1、trait的声明
trait 特质名 {
trait 体
}
(trait 命名 一般首字母大写)

2、一个类具有某种特质时,可以使用extends 关键字 ,如存在多个特质,那么必须使用with 关键字连接,例如:
1)没有父类
class 类名 extends 特质1 with 特质2 with 特质 3 …
2)有父类
class 类名 extends 父类 with 特质1 with 特质2 with 特质 3 … (有父类 必须先继承父类才行)

入门案例:

//定义一个 Trait01 特质
trait Trait01{
  //写了个抽象方法
  def getConnect()
}

//定义几个类使其有继承关系
class A{}
class B extends A{}
// 如果有继承关系 要先把继承的父类写在前面
class C extends B with Trait01 {
//重写了抽象方法
  override def getConnect(): Unit = {
    println("连接MySQL")
  }
}
    val c = new C
    c.getConnect()

class D{}
class E extends D{}
class F extends D with Trait01 {
  override def getConnect(): Unit = {
    println("连接oracle")
  }
}
    val f = new F
    f.getConnect()

3、trait 特质再说明:
特质可以拥有抽象方法和具体方法

4、带有特质的对象,动态混入:
除了可以在声明类时继承特质以外,还能在构建对象时混入特质,扩展目标类的功能
案例说明:

//定义一个特质
trait Operate3{
  def insert(id:Int): Unit ={
    println("插入数据:"+id)
  }
}
//普通类
class OracleDB{
}
//抽象类
abstract  class Mysql{
}
//抽象类含有抽象方法
abstract class mysql_1{
  def insert()
}

//普通类动态混入特质
val oracleDB = new OracleDB with Operate3
oracleDB.insert(12)

//抽象类无方法 混入动态特质
val mysql = new Mysql with Operate3
mysql.insert(18)

//抽象类 含有抽象方法的 进行动态混入
val my = new mysql_1 with Operate3 {
//其抽象方法必须被重写
      override def insert(): Unit = {
        println("插入数据")
      }
    }
my.insert(33)  //特质方法的调用
my.insert()   //重写了抽象类中方法的调用

5、扩展类的特质:
特质可以继承类,用来拓展该特质的功能

// 例如:
trait LoggedException extends Exception{
    def log(): Unit ={
      println(getMessage())   //方法来自于 Exception
    }
  }
class UnhappyException extends LoggedException{
    // 由于 LoggedException  继承了  Exception
    //UnhappyException 再继承 LoggedException
    // 所以 可以改写  getMessage 方法
    override def getMessage =
      "错误消息"
  }
val unhappyException = new UnhappyException
    println(unhappyException.getMessage)  //输出:错误消息

注意事项:
1、所有混入该特质的类,会自动成为那个特质所继承的超类的子类
2、如果混入该特质的类,已经继承了另一个类(A类),则要求A类是特质超类的子类,否则会出现多继承现象,报错

错误示例:

// 定义一个普通类
class CCC{}
class UnhappyException3 extends CCC with LoggedException{
override def getMessage: String = "错误消息!"
 }

//以上代码编译时会报错 因为CCC 不是 Exception 的 子类,从而产生了 多继承现象

6、自身类型:
解决特质的循环依赖问题,同时确保特质可以在不扩展某个类的情况下,依然可以做到限制混入该特质的类的类型。

// An highlighted block
trait Logger{
    //this:Exception => 明确告诉编译器,我就是Exception,
    // 如果没有这句话,下面的getMassage 不能调用
    this:Exception =>
    def log():Unit={
     //既然我就是Exception,那么就可以调用其中的方法
      println(getMessage)
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值