Scala-特质

news2024/9/28 13:19:32

特质

特质的混入用法

特质的叠加

特质和抽象类的区别

特质自身类型


特质

  • Scala 语言中,采用特质 trait(特征)来代替接口的概念,也就是说,多个类具有相同 的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。
  • Scala 中的 trait 中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可 以混入(mixin)多个特质。
  • 这种感觉类似于 Java 中的抽象类。 Scala 引入 trait 特征,第一可以替代 Java 的接口,第二个也是对单继承机制的一种 
trait 特质名 {
trait 主体
}

一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素, 所以在使用时,也采用了 extends 关键字,如果有多个特质或存在父类,那么需要采用 with 关键字连接。

没有父类:class 类名 extends 特质 1 with 特质 2 with 特质 3 …
有父类:class 类名 extends 父类 with 特质 1 with 特质 2 with 特质 3
  1. 类和特质的关系:使用继承的关系。
  2. 当一个类去继承特质时,第一个连接词是 extends,后面是 with。
  3. 如果一个类在同时继承特质和父类时,应当把父类写在 extends 后。

当父类和特质定义相同属性发生冲突时出现如下报错提示 则需要重写父类和特质的冲突属性 

object traits {
  def main(args: Array[String]): Unit = {
    //测试
    val st = new z
    st.hello()
    st.Run()
    st.study()

  }
}
//定义父类
class S{
  val name : String = "s"
  var age : Int = 20
  def hello(): Unit ={
    println("hello"+name)
  }
}

//定义特质
trait Young{
  //声明抽象和非抽象属性
  var age : Int
  val name : String = "young"

  //声明抽象和非抽象方法
  def play(): Unit ={
    println("playing games")
  }
  def Run(): Unit
}

//定义子类
class z extends S with Young {
  //重写冲突属性
  override val name : String = "zz"
  //重写特质抽象方法
  override def Run(): Unit = {
    println(s"${name}跑步")
  }
  //重写父类方法
  override def hello(): Unit = {
    super.hello()
    println("你好")
  }

  //定义子类方法
  def study(): Unit ={
    println(" 学习")
  }
}

 特质的混入用法

混入是可灵活的扩展类的功能

动态混入:创建对象时混入 trait,而无需使类混入该 trait

如果混入的 trait 中有未实现的方法,则需要实现

object traits {
  def main(args: Array[String]): Unit = {
    //测试
    val  st = new Ta
    st.study()
    st.increase()
    st.play()
    st.increase()
    println("------------------------------------------------")
    //动态混入
    val st2 = new Ta with Take {
      //重写特质3抽象类
      override def Singing(): Unit = println("唱歌")
      override def dancing(): Unit = println("跳舞")
    }
    st2.hello()
    st2.play()
    st2.Singing()
    st2.dancing()
    st2.increase()
  }
}
//定义父类
class S{
  val name : String = "s"
  var age : Int = 20
  def hello(): Unit ={
    println("hello"+name)
  }
}

//定义特质1
trait Young{
  //声明抽象和非抽象属性
  var age : Int
  val name : String = "young"

  //声明抽象和非抽象方法
  def play(): Unit ={
    println("playing games")
  }
  def Run(): Unit
}
//定义特质2
trait Knowledge{
  var amount: Int = 0
  def increase(): Unit
}

//定义特质用于动态混入
trait Take{
  def Singing(): Unit
  def dancing(): Unit
}

//定义混入特质类
class Ta extends S with Young with Knowledge {
  //重写冲突属性
  override val name: String = "zz"
  //重写S父类方法
  override def hello(): Unit = {
    super.hello()
    println("你好")
  }
  //定义子类方法
  def study(): Unit = {
    println(" 学习")
  }
  //重写Young特质抽象方法
  override def Run(): Unit = {
    println(s"${name}跑步")
  }
  //重写Knowledge特质抽象方法
  override def increase(): Unit = {
    amount += 1
    println(name+" :"+amount)
  }
}

特质的叠加

所谓的特质叠加,就是将混入的多个 trait 中的冲突方法叠加起来。

由于一个类可以混入(mixin)多个 trait,且 trait 中可以有具体的属性和方法,若混入 的特质中具有相同的方法(方法名,参数列表,返回值均相同),必然会出现继承冲突问题。 冲突分为以下两种:

  • 第一种,一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且 两个 trait 之间没有任何关系,解决这类冲突问题,直接在类(Sub)中重写冲突方法。

object traits {
  def main(args: Array[String]): Unit = {
    //测试
    val stt1 = new studentz
    stt1.increase()
  }
}
//定义特质1
trait Knowledge{
  var amount: Int = 0
  def increase(): Unit = {
    println("---->")
  }
}

//定义特质2
trait Take{
  def Singing(): Unit
  def dancing(): Unit
  def increase(): Unit = {
    println("<----")
  }
}
//定义父类
class S{
  val name : String = "s"
  var age : Int = 20
  def hello(): Unit ={
    println("hello"+name)
  }
  def increase(): Unit = {
    println("<------>")
  }
}
//定义叠加特质类
class studentz extends S with Knowledge with Take{
  //重写特质抽象方法
  override def Singing(): Unit = println("唱歌")
  override def dancing(): Unit = println("跳舞")

  override def increase(): Unit ={
    super.increase()
  }
}

  •  第二种,一个类(Sub)混入的两个 trait(TraitA,TraitB)中具有相同的具体方法,且 两个 trait 继承自相同的 trait(TraitC),及所谓的“钻石问题”,解决这类冲突问题,Scala 采用了特质叠加的策略。

object traits {
  def main(args: Array[String]): Unit = {
    //测试
    val my = new My
    println(my.describe())
  }
}
//定义super特质
trait A{
  def describe(): String = "AAAA"
}
//定义super特质的子特质1
trait B extends A{
  var b : String = "b"
  //重写特质super抽象方法
  override def describe(): String = super.describe()+b
}

//定义super特质的子特质2
trait C extends A {
  var c : String = "c"
  //重写特质super抽象方法
  override def describe(): String = super.describe()+c
}

//定义叠加特质类
class My extends B with C {
  //重写特质抽象方法
  override def describe(): String = super.describe()
}

 class My extends B with C

叠加顺序 C+B+A

  • 如果想要调用某个指定的混入特质中的方法,可以增加约束:super[],例如:

 特质和抽象类的区别

  1. 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
  2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数, 而特质不行(有无参构造)。

特质自身类型

_: 类型名称 =>

使用this.属性 或 类名.属性 可直接访问 

自身类型可实现依赖注入的功能。

object traits {
  def main(args: Array[String]): Unit = {
    //测试
    val user = new RegisterUser("name","password")
    user.insert()
  }
}
//定义用户类
class User(val name : String,val password : String)//没主体可省略花括号不写

trait UserDao{
  //定义自身类型
  _: User =>
  //向数据库插入数据
  def insert(): Unit ={
    println(s"insert into db :${this.name}")
  }
}

//定义子类注册用户类                                             继承父类属性            混入特质
class RegisterUser(name : String , password : String) extends User(name,password) with UserDao

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ELK + Kafka 测试

配置file beat输出到 Kafkalogstash服务器从kafka获取数据并输出到es集群在es集群上查看索引kibana界面添加索引查看数据1.配置file beat输出到 Kafka 1.1 Filebeat机器配置数据采集和输出目标 做好域名解析 # vim /usr/local/filebeat/filebeat.yml # 修改输出目标为kafka…

CRM客户管理系统哪个好用?盘点前十名!

CRM客户管理系统排行&#xff1f;盘点前十名&#xff01; CRM客户管理系统是一种集成多种功能的软件系统&#xff0c;可以帮助企业跟进和管理客户关系、提高销售业绩、优化营销策略等。对于企业来说&#xff0c;选择一款适合自己的CRM系统非常重要&#xff0c;因为它能够直接影…

使用kotlin编写html dsl框架

前排提醒&#xff0c;这个框架就是我写着玩的&#xff0c;如果您已经会使用vue或其他前端框架&#xff0c;这篇文章可能对您没有什么意义。即使您不会如上提到的框架&#xff0c;也不要对该框架报有过高的期待&#xff0c;该框架更多的是&#xff0c;我自己的自娱自乐。 这里还…

新闻格式的演变及其对我们消费新闻方式的影响

这些年来&#xff0c;我们消费新闻的方式发生了翻天覆地的变化&#xff0c;从印刷报纸和广播新闻时代到 24 小时新闻频道和数字新闻平台时代。随着新闻媒体的发展&#xff0c;新闻呈现的格式也发生了变化。今天&#xff0c;新闻格式在新闻如何被受众传播和理解方面起着至关重要…

工程机械焊接件焊接结构件三维扫描检测外观质量控制-CASAIM三维扫描检测仪

焊接已发展为制造业中的一种重要的加工方法&#xff0c;广泛应用于航空、航天、冶金、石油、汽车制造以及国防等领域。工程机械焊接件品种繁多、几何形状复杂&#xff0c;焊接件质量的好坏将直接影响到产品的使用寿命长短。对焊缝表面尺寸测量及评定表面焊缝缺陷时&#xff0c;…

不到3天给公司省下近10万,低代码是真给老板省钱

早上领导开组会提了个似曾相识的需求&#xff0c;客户想要一个点餐系统。需求是用户登录后可以直接享有会员权益&#xff0c;还要提供外卖管理系统、配送系统、数据中台、BI数据分析、系统托管等O2O解决方案。 这是餐饮业典型的业务场景&#xff0c;如果缺乏必要的数字化工具支…

GitLab分支管理规范

GitLab 分支管理规范 本规范用于描述日常研发流程中关于 GitLab 上代码分支使用的规则, 大家共同严格遵守规范, 避免出现分支管理混乱现象, 保证日常的发版上线工作顺利进行。 Workspace: 工作区, 平时我们写代码的地方Index: 暂存区, 写完代码后让它变成的待提交的状态Repos…

《系统架构设计》-05-架构模型(Architecture Model)

文章目录1. 概述1.1 模型1.2 软件设计领域的架构模型2. 领域模型&#xff08;Domain Model&#xff09;2.1 概念2.2 示例3. 设计模型&#xff08;Design Model&#xff09;3.1 概念3.2 创建过程4. 代码模型4.1 概念4.2 创建过程5. 三种模型的关系1. 概述 1.1 模型 诠释&#…

“华为杯”研究生数学建模竞赛2006年-【华为杯】A题:Ad Hoc 网络中的区域划分和资源分配问题(附获奖论文)

赛题描述 Ad Hoc网络是当前网络和通信技术研究的热点之一,对于诸如军队和在野外作业的大型公司和集团来说,Ad Hoc网络有着无需基站、无需特定交换和路由节点、随机组建、灵活接入、移动方便等特点,因而具有极大的吸引力。 在Ad Hoc网络中,节点之间的通信均通过无线传输来完…

黑马Spring学习笔记(三)——Spring整合MyBatis、Junit

一、Spring整合Mybatis 步骤1:项目中导入整合需要的jar包【pom.xml】<!--Spring操作数据库需要该jar包--> <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.20</version&g…

前端技术和框架

一、各种技术概述 1.HTML &#x1f9e8;HTML中文称为超文本标记语言&#xff0c;从语义上来说&#xff0c;它只是一种是一种标识性的语言&#xff0c;并不是一种编程语言。 <p>这是一段话</p>通过这个标签可以表示文本的一个段落。而且其中还有还有图片标签、视…

Dvwa及Sqli安装

Dvwa与Sqli安装资源准备Dvwa安装SQLI安装资源准备 链接&#xff1a;https://pan.baidu.com/s/1ZhPTmSgD-VaAevK-JyWtjQ 提取码&#xff1a;2hkd Dvwa安装 首先将Dvwa解压到phpstudy的www目录下&#xff1a; 然后进入到相应的config文件下&#xff0c;会发现一个dist结尾的文…

第三节 流程控制语句

流程控制语句 顺序结构 分支结构 if分支结构&#xff1a; 格式1: if(条件表达式){ 代码 } 格式2&#xff1a; if(条件表达式){ 代码 }else{ 代码 } 格式3&#xff1a; if(条件表达式){ 代码 }else if&#xff08;&#xff09;{ 代码 }else if&#xff08;&#xff09;{ 代码…

SpringCloud(五)MQ消息队列

MQ概念常见消息模型helloworld案例实现实现spring AMQP发送消息实现spring AMQP接收消息工作消息队列实现发布订阅模型Fanout Exchange实现DirectExchange实现TopicExchange实现DirectExchange 和FanoutExchange的差异DirectExchange 和TopicExchange的差异基于RabbitListener注…

浅谈hcip devops考试心得

官网&#xff1a;华为HCIP-Cloud Service DevOps Engineer 今天考过了hcip devops的考试&#xff0c;写两句&#xff0c;对于一些参加考试的朋友留下一点参考: 第一个问题&#xff0c;hcip还需要报班嘛&#xff1f; 我认为这一项是不需要的&#xff0c;有点浪费钱&#xff0c;…

软件测试人员会被替代吗?IT行业哪个方向的前景最好?字节12年测开是这样说的

互联网测试从业12年&#xff0c;前来作答。 逻辑上来说&#xff0c;软件工程最初始只需要两个岗位&#xff0c;一个是产品经理。&#xff0c;一个是研发&#xff08;开发&#xff09;&#xff0c;剩余的 所有岗位都是由他们衍生而来的。 第三个岗位大概率就是测试&#xff0c…

继电器的工作原理、构成和功能介绍

随着电力应用的不断发展&#xff0c;电气设备已经深入到我们的日常生活中&#xff0c;电气自动化技术大量使用在电力系统和生产型企业中&#xff0c;人们在享受电带来方便的同时要注意用电保护。继电器就是为了保护电路而生的&#xff0c;可以提高电路可靠性&#xff0c;保障用…

山洪径流过程模拟及洪水危险性评价

目录 1.洪水淹没危险性评价方法及技术讲解 2.GIS水文信息提取与分析(基于ArcGIS软件) 3.洪水淹没模拟水文分析&#xff1a;洪峰流量估算 4.洪水淹没模拟水力学分析&#xff1a;Hec-RAS实例操作 GIS水文分析&#xff08;ArcHydro、Spatial Anlysist等模块&#xff09;是流域…

从银行数字化转型来聊一聊,火山引擎 VeDI 旗下 ByteHouse 的应用场景

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 近日&#xff0c;火山引擎凭借云原生数据分析平台 ByteHouse&#xff0c;成功入围行业媒体 Internet Deep&#xff08;互联网周刊&#xff09;发布的《2022 云原生企…

【Linux】软件包管理器yum和编辑器vim的使用

文章目录1.软件包管理器yum1.1什么是软件包和软件包管理器1.2yum的介绍与使用2.编辑器vim2.1vim的基本概念2.2vim的基本操作2.3vim【Nomal mode】命令集2.4 vim末行模式命令集2.5 简单的vim配置1.软件包管理器yum 1.1什么是软件包和软件包管理器 在Linux下下载软件的方式是下…