文章目录

  • 特质(trait)
    • 概念
    • 语法
      • 继承特质
      • 继承单个trait 代码示例
      • 继承多个特质 代码示例
    • 定义具体的方法
      • 代码示例
    • trait中定义具体的字段和抽象的字段
      • 定义
      • 代码示例
    • 模板模式
      • 代码示例
    • 对象混入trait
      • 语法
      • 代码示例
    • trait调用链
      • 代码示例
    • trait的构造机制
    • 代码示例
    • trait继承class
      • 代码示例

特质(trait)

scala中没有Java中的接口(interface),替代的概念是——特质

概念

  • 特质是scala中代码复用的基础单元
  • 它可以将方法和字段定义封装起来,然后添加到类中
  • 与类继承不一样的是,类继承要求每个类都只能继承一个超类,而一个类可以添加任意数量的特质。
  • 特质的定义和抽象类的定义很像,但它是使用trait关键字

语法

trait 名称 {// 抽象字段// 抽象方法
}
继承特质
  • 使用extends来继承trait(scala不论是类还是特质,都是使用extends关键字)
  • 如果要继承多个trait,则使用with关键字
class 类 extends 特质1 with 特质2 {// 字段实现// 方法实现
}
继承单个trait 代码示例
object Test01 {//定义一个  日志   特质trait Logger {//抽象方法  接收控制带def log(message:String)}//定义一个控制台类 继承日志类 输出日志信息class ConsoleLogger extends Logger {override def log(message: String): Unit = println("控制台日志:\n" + message)}def main(args: Array[String]): Unit = {val logger = new ConsoleLoggerlogger.log("这是一条日志")}
}
继承多个特质 代码示例
object Test02 {//创建一个 消息发送  特质 添加 发送 方法trait MessageSender {//定义一个发送方法def send(msg:String)}//创建一个 消息接收  特质  添加 接收 方法trait MessageReceive {def receive() : String}//创建 消息工作 类 实现 接收和发送两个特质class MessageWorker extends MessageSender with MessageReceive {//继承发送方法override def send(msg: String): Unit = println(s"发送消息 : ${msg}")//继承接收方法override def receive(): String = "你好!我叫张三"}def main(args: Array[String]): Unit = {val worker = new MessageWorker//发送信息 helloworker.send("hello")//接收信息println(worker.receive())}
}

定义具体的方法

和类一样,trait中还可以定义具体的方法

代码示例
object Test03 {trait LoggerDetail {//在trait 中定义具体方法def log(msg:String): Unit = println(s"msg = ${msg}")}class UserService extends LoggerDetail {def add(): Unit = {//调用log 方法log("添加用户")}}def main(args: Array[String]): Unit = {val service = new UserService//调用add方法service.add()}
}

trait中定义具体的字段和抽象的字段

定义
  • 在trait中可以定义具体字段和抽象字段
  • 继承trait的子类自动拥有trait中定义的字段
  • 字段直接被添加到子类中
代码示例
object Test04 {//定义 日志 特质trait Logger {//定义一个SimpleDateFormat字段,用来格式化日期(显示到时间)val df = new SimpleDateFormat("yyyy-MM-dd HH:mm")//创建一个log抽象方法,用于输出日志def log(msg:String)}//创建ConsoleLogger类 转化当前时间并输出控制台信息class ConsoleLogger extends Logger {override def log(msg: String): Unit = {println(s"${df.format(new Date)}\t控制台消息:\n${msg}")}}def main(args: Array[String]): Unit = {//创建对象val logger = new ConsoleLogger//调用方法logger.log("NullPointerException")}
}

模板模式

  1. 在一个特质中,具体方法依赖于抽象方法,而抽象方法可以放到继承trait的子类中实现,这种设计方式也称为模板模式
  2. 在scala中,trait是可以定义抽象方法,也可以定义具体方法的
  • trait中定义了一个抽象方法
  • trait中定义了其他的几个具体方法,会调用抽象方法
  • 其他实现类可以来实现抽象方法
  • 真正调用trait中具体方法的时候,其实会调用实现类的抽象方法实现
代码示例
object Test05 {//定义一个 日志 特质trait Logger {//定义一个日志信息抽象方法def log(msg:String)//定义 info方法def info(msg:String): Unit = log("INFO:" + msg)//定义 warn 方法def warn(msg:String): Unit = log("WARN:" + msg)//定义 error 方法def error(msg:String): Unit = log("ERROR:" + msg)}//定义控制台 输出日志class ConsoleLogger extends Logger {override def log(msg: String): Unit = {println(msg)}}def main(args: Array[String]): Unit = {//创建对象val logger = new ConsoleLogger//调用方法logger.info("信息日志")logger.warn("警告日志")logger.error("错误日志")}
}

对象混入trait

scala中可以将trait混入到对象中,就是将trait中定义的方法、字段添加到一个对象中

语法
val/var 对象名 = new 类 with 特质
代码示例
object Test06 {//定义一个日志 特质trait Logger {//输出日志的方法def log(msg:String): Unit = println(msg)}class UserServicedef main(args: Array[String]): Unit = {val service = new UserService with Loggerservice.log("混入的方法")}
}

trait调用链

类继承了多个trait后,可以依次调用多个trait中的同一个方法,只要让多个trait中的同一个方法在最后都依次执行super关键字即可。类中调用多个tait中都有这个方法时,首先会从最右边的trait方法开始执行,然后依次往左执行,形成一个调用链条。

代码示例
object Test07 {//定义一个 处理 特质trait HandlerTrait {//定义一个处理 方法def handle(data:String): Unit = {println("处理数据....")}}//定义一个 数据验证的特质  继承 处理 特质trait DataValidHandlerTrait extends HandlerTrait {//重新处理 方法override def handle(data:String): Unit = {println("验证数据....")super.handle(data)}}//定义一个 签名校验 特质  继承处理特质trait SignatureValidHandlerTrait extends HandlerTrait {//重写处理方法override def handle(data: String): Unit = {println("效验签名...")super.handle(data)}}//定义一个支付 特质 继承 签名效验特质 和 数据验证特质class PayService extends DataValidHandlerTrait with SignatureValidHandlerTrait {//重写处理数据方法override def handle(data: String): Unit = {println("准备支付...")super.handle(data)}}def main(args: Array[String]): Unit = {val service = new PayServiceservice.handle("支付参数")}
}

trait的构造机制

  • trait也有构造代码,但和类不一样,特质不能有构造器参数
  • 每个特质只有**一个无参数**的构造器。
  • 一个类继承另一个类、以及多个trait,当创建该类的实例时,它的构造顺序如下:
  1. 执行父类的构造器
  2. 从左到右依次执行trait的构造器
  3. 如果trait有父trait,先构造父trait,如果多个trait有同样的父trait,则只初始化一次
  4. 执行子类构造器

代码示例

object Test08 {trait Logger {println("执行Logger构造器")}trait MyLogger extends Logger {println("执行MyLogger构造器")}trait TimeLogger extends Logger {println("执行TimeLogger构造器")}class Person {println("执行Person构造器")}class Student extends Person with TimeLogger with MyLogger {println("执行Student构造器")}def main(args: Array[String]): Unit = {new Student}
}

trait继承class

trait也可以继承class的。特质会将class中的成员都继承下来。

代码示例
object Test16 {//创建一个MyUtils类,定义printMsg方法class MyUtil {def printMsg(msg:String): Unit = {println(msg)}}//创建一个Logger特质,继承自MyUtils,定义log方法trait Logger extends MyUtil {def log(msg:String): Unit = {printMsg("Logger:" +msg)}}//创建一个Person类 继承Logger类class Person extends Logger {//实现sayHello方法,调用log方法def sayHello(): Unit = {log("你好")}}def main(args: Array[String]): Unit = {val person = new Personperson.sayHello()}
}

Scala 中的 特质(trait)相关推荐

  1. scala中使用特质中的抽象字段和实际字段

    Scala中,trait相当于Java中的接口,遇到需要使用Java接口的场景时,你就在scala中可以使用trait了. 我们知道Java中你可以实现多个接口,那么Scala中,你也可以继承多个tr ...

  2. scala基础之特质trait

    Scala中,trait相当于Java中的接口,遇到需要使用Java接口的场景时,你就在Scala中可以使用trait了. 我们知道Java中你可以实现多个接口,那么Scala中,你也可以继承多个tr ...

  3. Scala特质trait

    Scala特质 章节目标 能够使用trait独立完成适配器, 模板方法, 职责链设计模式 能够独立叙述trait的构造机制 能够了解trait继承class的写法 能够独立完成程序员案例 1. 特质入 ...

  4. Scala 034 特质trait

    文章目录 Scala 特质trait trait作为接口使用 trait中还可以定义具体的方法 trait中定义具体的字段和抽象的字段 使用trait实现模板模式 对象混入trait trait实现调 ...

  5. scala 基础十一 scala 中的trait特质

    1.Scala类型系统的基础部分是与Java非常相像的.Scala与Java一样有单一的根类,Java通过接口来实现多重继承,而Scala则通过特征(trait)来实现(Scala的特征可以包含实现代 ...

  6. 2021年大数据常用语言Scala(三十一):scala面向对象 特质(trait)

    目录 特质(trait) 作为接口使用 定义具体的方法 定义具体方法和抽象方法 定义具体的字段和抽象的字段 实例对象混入trait trait调用链 trait的构造机制 trait继承class 特 ...

  7. scala入门-07特质类(trait)的使用

    trait类似于Java8中的可用带default method的接口. trait中可以带有实现的方法,也可以带有抽象方法,使用trait的方法是with而混入类中. 我们在scala下的org.s ...

  8. Scala中特质的使用以及特质冲突

    说明 Scala语言中,采用特质trait来代替接口的概念.也就是说,多个类中,具有相同的特征时,可以将此特征独立出来,采用trait关键字声明. Scala特质中,既可以有抽象属性和抽象方法,也可以 ...

  9. Scala之特质特质Trait

    Scala之特质特质Trait 一.概述 Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait ...

最新文章

  1. Python全栈开发——描述符
  2. mac下在eclipse中怎样清除/切换svn
  3. PHP在程序处理过程中动态输出内容
  4. socketserver库的使用
  5. 期货市场技术分析02_趋势的基本概念
  6. icesat-2数据下载的几种方法
  7. python:查看函数方法的具体信息、参数等
  8. 鸿蒙 usb调试,usb调试助手
  9. c语言判断按下键盘,找出键盘上当前按下的键
  10. java : 实现微信网页授权,超详细!
  11. vue {{}}中小数保留几位小数的toFixed(小数位数)方法
  12. 51单片机基础——串口发送66,数码管显示66
  13. 大数据营销方案的分析处理
  14. Laravel5.5 项目开发文档,精简版,不适合新手使用。
  15. 五大领域总目标指南_幼儿园五大领域活动总目标
  16. matlab cdf 曲线不平滑,拟合经验CDF曲线以找到确切的值
  17. GetElementById
  18. uniapp 文本 字体 样式总结
  19. Oracle项目管理系统之概算模板
  20. 服务器 保密协议,云服务器保密协议

热门文章

  1. vue2 django前后端分离(一.环境搭建)
  2. 从100PV到1亿级PV网站架构演变(转)
  3. 比赛经验总结--187
  4. 青龙面板-简单获取京东CK
  5. 《神经网络与深度学习》-无监督学习
  6. 计算机word题如何设置加宽,职称计算机考试Word习题16
  7. python百度地图标注_利用python和百度地图API实现数据地图标注
  8. turtle实现一团乱麻和甜甜圈
  9. htb-shocker
  10. AI ProCon圆满落幕,五大技术专场精彩瞬间不容错过