ITPub博客

首页 > 数据库 > 数据库开发技术 > Scala快速入门-8-特质

Scala快速入门-8-特质

原创 数据库开发技术 作者:HelloTech技术派 时间:2018-01-07 09:00:00 0 删除 编辑

知识点

  • Scala和Java一样不允许类继承多个超类,特质解决这一局限性

  • 类可以实现任意数量的特质

  • 当将多个特质叠加在一起时,顺序很重要,其方法先被执行的特质排在更后面

  • Scala特质可以提供方法和字段的实现

  • 特质要求实现它们的类具备特定的字段、方法或超类

  • 特质可以同时拥有抽象方法和具体方法,而类可以实现多个特质

当做接口使用的特质

  • Scala特质完全可以像Java的接口一样,使用关键字 trait

  • 不需要将方法声明为abstract,特质中未被实现的方法默认就是抽象的

  • 在子类中重写特质的抽象方法不需要用 override 关键字

  1. package com.gemantic.base

  2. /**

  3.  * @author Yezhiwei

  4.  * @date 18/1/6

  5.  */

  6. object TraitLearn {

  7.  def main(args: Array[String]): Unit = {

  8.    val logger = new ConsoleLogger

  9.    logger.log("console log message...")

  10.  }

  11. }

  12. trait Logger {

  13.  def log(msg: String)

  14. }

  15. class ConsoleLogger extends Logger {

  16.  override def log(msg: String): Unit = println(msg)

  17. }

说明:

子类实现特质,用 extends 而不是 implements

不需要写 override

如果需要多个特质,可以用with关键字来添加额外的特质,如下代码

  1. class ConsoleLogger extends Logger with Serializable {

  2.  override def log(msg: String): Unit = println(msg)

  3. }

带有具体实现的特质

  • 在Scala的特质中的方法并不需要一定是抽象的

  • 子类从特质得到了一个具体的log方法实现

  1. trait ConsoleLoggerImp {

  2.  def log(msg: String) {println(msg)}

  3. }

  4. class AccountAction extends Account with ConsoleLoggerImp {

  5.  def withdraw(amount: Double): Unit = {

  6.    if (amount > nowBalance) {

  7.      log("insufficient funds")

  8.    } else {

  9.      log("enough funds")

  10.    }

  11.  }

  12. }

  13. object TraitLearn {

  14.  def main(args: Array[String]): Unit = {

  15.    // 当做接口使用的特质

  16.    val logger = new ConsoleLogger

  17.    logger.log("console log message...")

  18.    // 带有具体实现的特质

  19.    val accountAction = new AccountAction

  20.    accountAction.withdraw(1000)

  21.  }

  22. }

带有特质的对象

  • 在构造单个对象时,可以为它添加特质

  • 在定义子类时可以使用不做任何实现的特质,在构造具体对象的时候混入一个更合适的实现

  • 特质中重写抽象方法,必须在方法上使用 abstract 及 override

  1. // 有默认实现,但是什么也没有做

  2. trait Logged {

  3.  def log(msg: String) {}

  4. }

  5. trait FileLogged extends Logged {

  6.  override def log(msg: String): Unit = println("saving file : " + msg)

  7. }

  8. class AccountAction extends Account with Logged {

  9.  def withdraw(amount: Double): Unit = {

  10.    if (amount > nowBalance) {

  11.      log("insufficient funds")

  12.    } else {

  13.      log("enough funds")

  14.    }

  15.  }

  16. }

  17. object TraitLearn {

  18.  def main(args: Array[String]): Unit = {

  19.    // 带有特质的对象,可以混入不同的日志

  20.    val accountActionLogger = new AccountAction with FileLogged

  21.    accountActionLogger.withdraw(1000)

  22.  }

  23. }

  24. // 运行输出结果

  25. saving file : insufficient funds

叠加在一起的特质

  • 可以为类或对象添加多个互相调用的特质,从最后一个开始被处理

  1. // 为日志增加时间戳

  2. trait TimestampLogged extends Logged {

  3.  override def log(msg: String): Unit = super.log(new java.util.Date() + " " +  msg)

  4. }

  5. // 如果日志内容长度超过10,截断

  6. trait ShortLogged extends Logged {

  7.  override def log(msg: String): Unit = super.log(if (msg.length <= 10) msg else msg.substring(0, 10) + "...")

  8. }

  9. object TraitLearn {

  10.  def main(args: Array[String]): Unit = {

  11.    // 带有特质的对象

  12.    val accountActionLogger = new AccountAction with FileLogged with TimestampLogged with ShortLogged

  13.    accountActionLogger.withdraw(1000)

  14.    val accountActionLogger1 = new AccountAction with FileLogged with ShortLogged with TimestampLogged

  15.    accountActionLogger1.withdraw(1000)

  16.  }

  17. }

  18. // 输出结果为

  19. saving file : Sat Jan 06 12:38:07 CST 2018 insufficie...

  20. saving file : Sat Jan 06...

  • 注意上面的特质调用顺序及log方法每一个都将修改过的消息传递给supper.log

特质构造顺序

  • 和类一样,特质也可以有构造器,由字段的初始化和其他特质体中的语句构成

  • 构造器执行顺序

首先调用超类的构造器

特质构造器在超类构造器之后、类构造器之前执行

特质由左到右被构造

每个物质当中,父特质先被构造

如果多个特质共有一个父特质,而那个父特质已经被构造,则不会再次构造

所有的特质构造完毕,子类被构造

  • 示例

  1. class AccountAction extends Account with FileLogged with ShortLogged {

  2.    ...

  3. }

构造器执行顺序如下

超类 Account

Logged ,第一个特质的父特质

FileLogged 第一个特质

ShortLogged 第二个特质,它的父特质Logged已被构造

AccountAction 子类


敬请期待下一篇<高阶函数>~


原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73725