scala特质

scala中提供了“trait(特质)”这个特殊概念,特质并非接口,它可以同时拥有抽象方法和具体方法,一个类可以拥有多个特质,这一特性解决了java接口的问题。

类可以通过“extends”关键字继承trait,这里不是implement,二是extends,类继承了trait后必须实现trait中的抽象方法,实现时不需要使用“override”关键字。scala中不支持类的多继承,但支持trait多继承,使用“with”关键字链接多个trait。

trait不仅可以定义抽象方法,还可以定义具体实现的方法。

特质还可以这样使用在创建对象时使用“with”关键字为其增加trait,并实现相应的抽象方法

trait中可以定义具体或抽象的字段,当一个类继承了这个trait,表明这个类拥有了trait中的字段,不需要使用“super”;而继承一个类,表明可以调用父类中的子弹,但不拥有字段,使用“super”关键字。

多个特质的构造顺序,有一个例子说明一下:

trait Logged {
  println("Logged构造器")
  def log(msg : String){
    println(msg)
  }
}

trait TimeLog  extends Logged{ 
  println("TimeLog构造器")
  override def log(msg : String){
    println("this is TimeLog : " + msg)
    super.log(new java.util.Date() + ",msg")
  }
}

trait SplitLog extends Logged{
  println("SplitLog构造器")
  val splitNum = 15
  override def log(msg : String){
    println("this is SplitLog : " + msg) 
    super.log(if(msg.length() > splitNum) msg.substring(0, splitNum) else msg)
  }
}

class Student extends TimeLog with SplitLog{
  def sayHello {
    log("liumingxin,liumingxin,liumingxin")
    println("hello")
  }
}

object StudentApp extends App{
  val s = new Student
  s.sayHello
}

//----------------------------
//运行结果
Logged构造器
TimeLog构造器
SplitLog构造器
this is SplitLog : liumingxin,liumingxin,liumingxin
this is TimeLog : liumingxin,lium
Thu Aug 16 10:39:09 CST 2018,msg
hello

继承多个trait的时候,总体原则是“从左到右,从父到子构造;从右到左,从子到父调用”。

自身类型(selftype)

有很多特质不是所有类都能随随便便继承的,例如异常类所能继承的特质,其他类继承并不合适,所以需要对特质加以约束。

通过“this : T => {}”的形式,指定这个特质只能被T或T的子类继承

trait ExceptionLog extends Logged{
  //
  //this : Exception => {}以外的区域不能写代码,否则会报错
  //
  this : Exception => {
    println("Logged构造器")
    def log(msg : String){
      println(msg)
    }
  }
}

也可以通过“this : {}  => {}”的形式,指定这个特质能被继承的规则,“this : {}”中的“{}”就可以设置规则,比如必须拥有指定对象、方法的类才能继承这个特质。

必须拥有“def getLog() : String”这个方法的类才能继承此trait

trait ExceptionLog extends Logged{
 this : {def getLog() : String} => {
    def log(msg : String){
      println(msg)
    }
  }
}

必须拥有“val log : String”这个常量的类才能继承此trait

trait ExceptionLog extends Logged{
 this : {val log : String} => {
    def log(msg : String){
      println(msg)
    }
  }
}

必须同时拥有“val log : String”和“def getLog() : String”的类才能继承此trait

trait ExceptionLog extends Logged{
 this : {
    val log : String
    def getLog() : String} => {
    def log(msg : String){
      println(msg)
    }
  }
}

需要注意的是,只能定义一次自身类型,不能定义多个this

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值