Scala学习笔记10: 特质

目录

    • 第十章 特质
      • 1- 特质
      • 2- 带有具体实现的特质
      • 3- 带有特质的对象
      • 4- 在特质中重写抽象方法
      • 5- 特质中的字段
      • 6- 特质构造顺序
      • 7- 扩展类的特质
      • 8- 自身类型
      • end

第十章 特质

在Scala中, 特质(Tratis) 是一种非常强大的特性, 可以为类提供额外的功能, 类似于 Java中的接口 ;

特质可以包含抽象方法、具体方法、字段等, 并且可以被类混入以增强类的功能 .

1- 特质

在Scala中, 特质 (Traits) 是一种类似于 Java 接口的概念, 但比接口更加强大和灵活 ;

特质可以包含抽象方法、具体方法、字段和构造函数, 可以被类混入 (Mixed-in) 以提供额外的功能, 类型于多重继承的概念 ;

  1. 定义特质: 特质可以使用 trait 关键字定义 ; 特质可以包含抽象方法、具体方法和字段 .

    trait Printable {def print(): Unit = {println("Printing...")}
    }
    
  2. 混入特质: 类可以通过 with 关键字混入特质, 从而获得特质中定义的方法和属性 ;

    class Document extends Printable {override def print(): Unit = {println("Printing document...")}
    }
    
  3. 特质组合: Scala允许类混入多个特质, 从而实现更灵活的功能组合 ;

    trait Printable {def print(): Unit = {println("Printing...")}
    }trait Loggable {def log(message: String): Unit = println(s"Logging: $message")
    }class Document extends Printable with Loggable {// Document 类混入(实现)了 Printable 和 Loggable 两个特质
    }
    
  4. 特质的构造函数: 特质可以有自己的构造函数, 可以接受参数;

    trait Greetable {val greeting: Stringdef greet(): Unit = println(s"$greeting")
    }
        class Person(val name: String) extends Greetable {val greeting: String = s"Hello, my name is $name"}val person = new Person("John")person.greet() // 输出: Hello, my name is John
    

2- 带有具体实现的特质

在Scala中, 特质(Traits) 可以包含具体实现的方法 ;

这种特质通常用于提供一些通用的功能或默认行为, 可以被混入到类中以增强类的功能 ;

示例:

    // 定义一个带有具体实现的特质trait Greeting {def greet(): Unit = {println("Hello, welcome!")}}// 定义一个类并混入带有具体实现的特质class Person(name: String) extends Greeting {def displayName(): Unit = {println(s"My name is $name")}}// 创建一个Person对象val person = new Person("John")person.greet() // 输出: Hello, welcome!person.displayName() // 输出: My name is John
  • 在上面的示例中, 特质 Greeting 定义了一个具有默认实现的 greet() 方法 ;
  • Person 混入了这个特质, 并且可以调用 greet() 方法来输出欢迎消息 ;
  • 同时, 类 Person 还定义了自己的方法 displayName() 来展示人名 ;

通过使用带有具体实现的特质, 可以在Scala中实现代码的复用和组合, 使代码更加模块化和灵活 .

3- 带有特质的对象

特质的对象是指通过特质创建的实例, 可以在特质中定义方法和字段, 并在类中混入特质后使用这些方法和字段 ;

示例:

    // 定义一个特质, 包含一个抽象方法和一个具体方法trait Printable {def print(): Unit // 抽象方法def defaultPrint(): Unit = println("Printing...") // 具体方法}// 定义一个类 Class, 混入特质class MyClass extends Printable {def print(): Unit = println("Custom print") // 实现抽象方法}// 创建特质对象和类对象val traitObject = new Printable {def print(): Unit = println("Trait object print") // 实现抽象方法}val classObject = new MyClass()// 调用特质对象的方法和类对象的方法traitObject.print() // 输出: Trait object printtraitObject.defaultPrint() // 输出: Printing...classObject.print() // 输出: Custom printclassObject.defaultPrint() // 输出: Printing... 
  • 在上面的示例中, 我们定义了一个特质 Printable , 其中包含一个抽象方法 print() 和一个具体方法 defaultPrint() ;
  • 然后我们创建了一个特质对象 traitObject 和一个类对象 classObject , 分别实现了特质中的抽象方法 ;
  • 通过特质对象和类对象, 我们可以调用特质中定义的方法 .

特质的对象在Scala中提供了一种灵活的方式来组织和重用代码, 同时增强类的功能 .

4- 在特质中重写抽象方法

在Scala中, 可以在新的特质中重写已经存在的抽象方法 ;

这种情况通常发生在需要扩展或修改现有特质功能时 ;

示例:

    // 定义一个原始特质TraitA, 包含一个抽象方法trait TraitA {def greet(): Unit = {} // 抽象方法}// 定义一个新的的特质TraitB, 继承TraitA, 并实现抽象方法trait TraitB extends TraitA {override def greet(): Unit = {println("Modified Greeting from TraitB")super.greet() // 调用父类的greet方法}}// 定义一个类Class, 混入新的特质 TraitBclass MyClass extends TraitA with TraitB {override def greet(): Unit = {println("Greeting from Class") // 实现抽象方法}}// 创建一个类对象val myClass = new MyClass()myClass.greet() // 输出: Greeting from Class
  • 在上面的示例中, 我们定义了一个原始特质 TraitA, 其中包含一个抽象方法 greet() ;
  • 然后, 我们定义了一个新的特质 TraitB , 继承自 TraitA, 并重写了 TraitA 中的抽象方法 ;
  • MyClass 混入了 TraitATraitB , 并实现了 TraitA 中的抽象方法 ;

通过这种方式, 我们可以在新的特质中重写已有特质的抽象方法, 并在类中使用这些特质类实现灵活的功能扩展 .

5- 特质中的字段

在Scala中, 特质(Traits) 可以包含字段(field), 这些字段可以是抽象的, 具体的或者带有初始值 ;

特质中的字段可以被混入的类访问和使用 ;

  1. 抽象字段: 特质中的抽象字段需要再混入的类中被具体化 ;

        trait Printable {val message: String // 抽象字段def printMessage(): Unit = {println(s"Printing: $message")}}class MyClass extends Printable {val message: String = "Hello, World!" // 具体化抽象字段}val myClass = new MyClass()myClass.printMessage() // 输出: Printing: Hello, World!
    
  2. 具体字段: 特质中的具体字段可以直接访问 ;

        // 特质中的具体字段trait Greeting {val greeting: String = "Hello" // 具体字段def greet(name: String): Unit = {println(s"$greeting, $name!")}}class Person extends Greeting {def greetTwice(name: String): Unit = {greet(name)greet(name)}}val person = new Person()person.greetTwice("John") // 输出: Hello, John! Hello, John!
    
  3. 带有初始值的字段: 特质中的字段可以带有初始值, 这些字段可以被混入的类直接使用 ;

        trait Config {val configName: String = "DefaultConfig" // 带有初始值的字段def printConfig() = println(s"Using config: $configName")}class AppConfig extends Config {override val configName: String = "ProductionConfig" // 覆盖特质中的字段}val appConfig = new AppConfig()appConfig.printConfig() // 输出: Using config: ProductionConfig
    

通过在特质中定义字段, 可以为类提供一些通用的属性或状态, 并且可以子啊混入的类中对这些字段进行具体化或覆盖 .

6- 特质构造顺序

在Scala中, 特质(Traits) 的构造器顺序遵循一下规则:

  1. 特质的构造顺序是从最顶层的特质开始, 逐级向下构造 ;
  2. 如果一个特质继承了另一个特质, 那么被继承的特质会被构造 ;
  3. 如果一个类混入了多个特质, 特质的构造顺序是从左到右 ;

示例:

    trait A {println("Trait A is constructed.")}trait B {println("Trait B is constructed.")}trait C extends A with B {println("Trait C is constructed.")}class MyClass extends C {println("Class MyClass is constructed.")}val myClass = new MyClass()// Output:// Trait A is constructed.// Trait B is constructed.// Trait C is constructed.// Class MyClass is constructed.
  • 在上面的示例中, 特质 C 继承了特质 AB , 并且按照从左到右的顺序构造 ;
  • 当创建 MyClass 类的实例时, 特质和类的构造器顺序如下:
    1. 首先构造 TraitA , 输出: Trait A is constructed.
    2. 然后构造 TraitB , 输出: Trait B is constructed.
    3. 接着构造 TraitC , 输出: Trait C is constructed.
    4. 最后构造 Class MyClass , 输出: Class MyClass is constructed.

通过理解特质的构造顺序规则, 可以更好地控制和理解Scala中特质的初始化过程 .

7- 扩展类的特质

在Scala中, 可以通过扩展类的特质来为类添加额外的功能 ;

特质可以被类混入, 从而使类具有特质中定义的方法和字段 ;

示例:

    // 定义一个特质, 包含一个方法和一个字段trait Printable {def printMessage(): Unit = println("Printing message...")val message: String}// 定义一个类, 混入特质并实现特质中的字段class MyClass extends Printable {val message = "Hello World!"}// 创建一个对象, 并调用特质中的方法val myClass = new MyClass()myClass.printMessage() // Output: Printing message...println(myClass.message) // Output: Hello World!
  • 在上面的示例中, 特质 Printable 定义了一个方法 printMessage() 和一个抽象字段 message ;
  • MyClass 扩展了特质 Printable 并实现了特质中的字段 ;
  • 通过创建 MyClass 类的实例, 我们可以调用特质中的方法和访问特质中定义的字段 ;

通过扩展类的特质, 可以实现代码的复用和组合, 使类具有更多的灵活性和功能 .

8- 自身类型

在Scala中, 特质的自身类型(self-type) 是一种机制, 用于指定混入该特质的类必须混入另一个特质或类 ;

通过自身类型, 可以要求混入特质的类必须满足特制的类型要求 ;

示例:

    // 定义一个特质 User, 表示具有用户名的特质trait User {def username: String}// 定义一个特质 Tweeter, 要求混入该特质的类必须也混入 User 特质trait Tweeter {this: User => // 自身类型, 要求混入Tweeter 的类必须也混入 User 特质def tweet(tweetText: String): Unit = println(s"$username: $tweetText")}// 定义一个类 VerifiedTweeter, 混入 Tweeter 和 User 特质class VerifiedTweeter(val name: String) extends Tweeter with User {def username: String = s"real $name"}// 创建 VerifiedTweeter 实例, 并调用 tweet 方法val alex = new VerifiedTweeter("Alex")alex.tweet("Hello, world!") // 输出: real Alex: Hello, world!
  • 在上面的示例中, 特质 Tweeter 使用自身类型 (this: User =>) 要求混入改特质的类必须也混入 User 特质 ;
  • VerifiedTweeter 混入了 TweeterUser 特质, 并实现了 suername 方法 ;
  • 通过使用自身类型, 可以在特质中知道类必须满足的类型要求, 从而增强代码的类型安全性 ;

end

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

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

相关文章

开源低代码平台技术为数字化转型赋能!

实现数字化转型升级是很多企业未来的发展趋势,也是企业获得更多发展商机的途径。如何进行数字化转型?如何实现流程化办公?这些都是摆在客户面前的实际问题,借助于开源低代码平台技术的优势特点,可以轻松助力企业降低开…

设计模式-装饰器模式(结构型)

装饰器模式 装饰器模式是一种结构模式,通过装饰器模式可以在不改变原有类结构的情况下向一个新对象添加新功能,是现有类的包装。 图解 角色 抽象组件:定义组件的抽象方法具体组件:实现组件的抽象方法抽象装饰器:实现…

沐风老师3DMAX一键多孔结构建模插件Porous使用方法

​3DMAX一键多孔结构建模插件Porous使用教程 3dMax是大家熟知的3D建模软件之一,其功能非常的强大,在科研绘图领域有着非常广泛的应用,但是由于科研绘图的图形(模型)一般都属于异形结构,手工绘制建模&#x…

mysql设置允许外部ip访问,局域网IP访问

(支持MYSQL8版本) 1. 登录进入mysql;mysql -uroot -p输入密码进入 2. 输入以下语句,进入mysql库,查看user表中root用户的访问 use mysql; select host,user from user; 3. 更新user表中root用户域属性&#xff0c…

Docker核心架构原理的深入分析

一、前言 由于平常工作中对Docker使用还是比较频繁的,但是一般都是基础的功能使用,并未对其核心架构原理做梳理,因此抽空简单总结一下这玩意的一些核心概念点知识,以备后面求职工作时可以更为深入地了解这个容器化工具。 二、Do…

springboot与flowable(2):流程部署

一、创建项目 创建springboot项目添加相关依赖。 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.…

【Rust日报】欢迎Rust-C++互操作性工程师Jon Bauman加入Rust基金会团队

欢迎Rust-C互操作性工程师Jon Bauman加入Rust基金会团队 原文链接 https://foundation.rust-lang.org/news/welcoming-rust-c-interoperability-engineer-jon-bauman-to-the-rust-foundation-team/ Jon Bauman 是一位在技术领域拥有二十年经验的资深工程师&#xff0c;涉及多个…

Upscayl:款利用人工智能技术,深度学习算法,实现图像无损放大和增强的强大工具。

Upscayl AI&#xff1a; Upscayl AI是一款基于先进的人工智能技术&#xff0c;特别是深度学习算法开发的图像增强工具。它能够智能地分析并改善图像质量&#xff0c;实现无损放大、细节重建和模糊消除&#xff0c;让老旧、低分辨率或模糊的照片焕发新生&#xff0c;达到高清画…

工程师 - VMware workstation pro个人版现已免费

May 13, 2024 VMware 桌面虚拟机管理程序(VMware Desktop Hypervisors) 使用行业标准桌面管理程序 VMware Workstation Pro for Windows 和 Linux 或 VMware Fusion for Mac 运行 Windows、Linux 和其他虚拟机。 Run Windows, Linux and other virtual machines with VMware Wo…

「51媒体」江苏媒体宣传报道,邀请媒体报道资源汇总

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 江苏作为中国东部的重要省份&#xff0c;拥有丰富的媒体资源&#xff0c;包括电视台、广播电台、报纸以及网络媒体。 电视台 江苏卫视&#xff1a;作为江苏省唯一的省级卫视台&#xff…

Java面试_数据库篇_优化,事务,Mysql

Java面试_数据库篇_优化,事务,Mysql 优化如何定位慢查询方案一: 开源工具方案二: Mysql自带慢日志 如何分析慢SQL语句索引介绍索引聚簇索引和非聚簇索引&#xff0c;回表查询覆盖索引&#xff0c;超大分页优化索引创建的原则索引失效 谈谈sql优化的经验 事务事务特性隔离级别un…

system 和 exec 的区别

在 linux 中&#xff0c;使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下&#xff1a; system 中创建了一个子进程&#xff0c;在子进程中执行用户的命令&#xff0c;子进程执行完毕之后&#xff0c;system 会返回。exec 不会创建子进程&#xff0c;…

跟着大佬学RE(六)

findKey 嗯&#xff0c;就是一个窗口程序&#xff0c;没有输入&#xff0c;flag 应该就藏在程序里面 第一遍自己直接莽做&#xff0c;在string窗口&#xff0c;找到 flag{} 看到标红直接 nop 然后&#xff0c;然后就不知道怎么搞了 这串字符提示不能随便 nop &#xff0c;重新…

虚幻引擎5 Gameplay框架(五)

Gameplay重要类及重要功能使用方法&#xff08;四&#xff09; DeveloperSetting DeveloperSetting是在虚幻引擎中是一个基类&#xff0c;主要用于创建和管理开发者设置相关的类。这类设置允许开发者自定义或调整项目中的各种配置选项&#xff0c;而无需直接修改代码或构建设置…

力扣2389.和有限的最长子序列

力扣2389.和有限的最长子序列 排序 前缀和二分 class Solution {public:vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {sort(nums.begin(),nums.end());for(int i1;i<nums.size();i)nums[i] nums[i-1];for(int &…

大模型应用开发框架LangChain

LangChain是什么&#xff1f; 它是针对大语言模型开发的一个开源的抽象框架。下图以github的流行度为例&#xff0c;可以看到langchain在很短的时间流行度达到Pytorch框架的高度&#xff0c;在AI燤火的当下&#xff0c;非常的流行。 上图&#xff0c;可以看到短短不到1年&…

AMD在行动:揭示应用程序跟踪和性能分析的力量

AMD in Action: Unveiling the Power of Application Tracing and Profiling — ROCm Blogs 导言 Rocprof是一款强大的工具&#xff0c;设计用于分析和优化基于AMD ROCm平台上运行的HIP程序的性能&#xff0c;帮助开发者找出并解决性能瓶颈。Rocprof提供了多种性能数据&#x…

每日一题——Python实现PAT乙级1099 性感素数(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 专业点评 时间复杂度分析 空间复杂度分析 综合点评 我要更强 优化点 …

人事信息管理系统(Java+MySQL)

一、项目背景 在现代企业中&#xff0c;管理大量员工的工作信息、薪资、请假、离职等事务是一项非常繁琐和复杂的任务。传统的手工管理方式不仅效率低下&#xff0c;而且容易出错。为了提高人事管理的效率&#xff0c;减少人工操作带来的错误&#xff0c;企业迫切需要一个高效…

[每日一练]首字母的大写和pandas关于字符串操作的代码拓展

该题目来源于力扣&#xff1a; 1667. 修复表中的名字 - 力扣&#xff08;LeetCode&#xff09; 题目要求&#xff1a; 将姓名列的首字母大写&#xff0c;按照id列进行排序&#xff1a; 输入&#xff1a; Users table: ---------------- | user_id | name | --------------…