scala学习笔记-面向对象编程之Trait
将trait作为接口使用
1 // Scala中的Triat是一种特殊的概念2 // 首先我们可以将Trait作为接口来使用,此时的Triat就与Java中的接口非常类似3 // 在triat中可以定义抽象方法,就与抽象类中的抽象方法一样,只要不给出方法的具体实现即可4 // 类可以使用extends关键字继承trait,注意,这里不是implement,而是extends,在scala中没有implement的概念,无论继承类还是trait,统一都是extends5 // 类继承trait后,必须实现其中的抽象方法,实现时不需要使用override关键字6 // scala不支持对类进行多继承,但是支持多重继承trait,使用with关键字即可7 8 trait HelloTrait {9 def sayHello(name: String) 10 } 11 trait MakeFriendsTrait { 12 def makeFriends(p: Person) 13 } 14 class Person(val name: String) extends HelloTrait with MakeFriendsTrait with Cloneable with Serializable { 15 def sayHello(name: String) = println("Hello, " + name) 16 def makeFriends(p: Person) = println("Hello, my name is " + name + ", your name is " + p.name) 17 }
在Trait中定义具体方法
1 // Scala中的Triat可以不是只定义抽象方法,还可以定义具体方法,此时trait更像是包含了通用工具方法的东西// 有一个专有的名词来形容这种情况,就是说trait的功能混入了类2 // 举例来说,trait中可以包含一些很多类都通用的功能方法,比如打印日志等等,spark中就使用了trait来定义了通用的日志打印方法3 4 trait Logger {5 def log(message: String) = println(message)6 }7 8 class Person(val name: String) extends Logger {9 def makeFriends(p: Person) { 10 println("Hi, I'm " + name + ", I'm glad to make friends with you, " + p.name) 11 log("makeFriends methdo is invoked with parameter Person[name=" + p.name + "]") 12 } 13 }
在Trait中定义具体字段
1 // Scala中的Triat可以定义具体field,此时继承trait的类就自动获得了trait中定义的field2 // 但是这种获取field的方式与继承class是不同的:如果是继承class获取的field,实际是定义在父类中的;而继承trait获取的field,就直接被添加到了类中3 4 trait Person {5 val eyeNum: Int = 26 }7 8 class Student(val name: String) extends Person {9 def sayHello = println("Hi, I'm " + name + ", I have " + eyeNum + " eyes.") 10 }
在Trait中定义抽象字段
// Scala中的Triat可以定义抽象field,而trait中的具体方法则可以基于抽象field来编写 // 但是继承trait的类,则必须覆盖抽象field,提供具体的值trait SayHello {val msg: Stringdef sayHello(name: String) = println(msg + ", " + name) }class Person(val name: String) extends SayHello {val msg: String = "hello"def makeFriends(p: Person) {sayHello(p.name)println("I'm " + name + ", I want to make friends with you!")} }
为实例混入trait
1 // 有时我们可以在创建类的对象时,指定该对象混入某个trait,这样,就只有这个对象混入该trait的方法,而类的其他对象则没有2 3 trait Logged {4 def log(msg: String) {}5 }6 trait MyLogger extends Logged {7 override def log(msg: String) { println("log: " + msg) }8 } 9 class Person(val name: String) extends Logged { 10 def sayHello { println("Hi, I'm " + name); log("sayHello is invoked!") } 11 } 12 13 val p1 = new Person("leo") 14 p1.sayHello 15 val p2 = new Person("jack") with MyLogger 16 p2.sayHello
trait调用链
1 // Scala中支持让类继承多个trait后,依次调用多个trait中的同一个方法,只要让多个trait的同一个方法中,在最后都执行super.方法即可2 // 类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依次往左执行,形成一个调用链条3 // 这种特性非常强大,其实就相当于设计模式中的责任链模式的一种具体实现依赖4 trait Handler {5 def handle(data: String) {}6 }7 trait DataValidHandler extends Handler {8 override def handle(data: String) {9 println("check data: " + data) 10 super.handle(data) 11 } 12 } 13 trait SignatureValidHandler extends Handler { 14 override def handle(data: String) { 15 println("check signature: " + data) 16 super.handle(data) 17 } 18 } 19 class Person(val name: String) extends SignatureValidHandler with DataValidHandler { 20 def sayHello = { println("Hello, " + name); handle(name) } 21 } 22
在trait中覆盖抽象方法
1 // 在trait中,是可以覆盖父trait的抽象方法的2 // 但是覆盖时,如果使用了super.方法的代码,则无法通过编译。因为super.方法就会去掉用父trait的抽象方法,此时子trait的该方法还是会被认为是抽象的3 // 此时如果要通过编译,就得给子trait的方法加上abstract override修饰4 5 trait Logger {6 def log(msg: String)7 }8 9 trait MyLogger extends Logger { 10 abstract override def log(msg: String) { super.log(msg) } 11 } 12 13 14
混合使用trait的具体方法和抽象方法
1 // 在trait中,可以混合使用具体方法和抽象方法2 // 可以让具体方法依赖于抽象方法,而抽象方法则放到继承trait的类中去实现3 // 这种trait其实就是设计模式中的模板设计模式的体现4 5 trait Valid {6 def getName: String7 def valid: Boolean = {8 getName == "leo" 9 } 10 } 11 class Person(val name: String) extends Valid { 12 println(valid) 13 def getName = name 14 } 15 16 17 18
trait的构造机制
1 // 在Scala中,trait也是有构造代码的,也就是trait中的,不包含在任何方法中的代码2 // 而继承了trait的类的构造机制如下:1、父类的构造函数执行;2、trait的构造代码执行,多个trait从左到右依次执行;3、构造trait时会先构造父trait,如果多个trait继承同一个父trait,则父trait只会构造一次;4、所有trait构造完毕之后,子类的构造函数执行3 4 class Person { println("Person's constructor!") }5 trait Logger { println("Logger's constructor!") }6 trait MyLogger extends Logger { println("MyLogger's constructor!") }7 trait TimeLogger extends Logger { println("TimeLogger's constructor!") }8 class Student extends Person with MyLogger with TimeLogger {9 println("Student's constructor!") 10 } 11 12 13 14 15 16
trait field的初始化
1 // 在Scala中,trait是没有接收参数的构造函数的,这是trait与class的唯一区别,但是如果需求就是要trait能够对field进行初始化,该怎么办呢?只能使用Scala中非常特殊的一种高级特性——提前定义2 trait SayHello {3 val msg: String4 println(msg.toString)5 }6 7 class Person8 val p = new {9 val msg: String = "init" 10 } with Person with SayHello 11 12 class Person extends { 13 val msg: String = "init" 14 } with SayHello {} 15 16 // 另外一种方式就是使用lazy value 17 trait SayHello { 18 lazy val msg: String = null 19 println(msg.toString) 20 } 21 class Person extends SayHello { 22 override lazy val msg: String = "init" 23 } 24 25 26 27
trait继承class
1 // 在Scala中,trait也可以继承自class,此时这个class就会成为所有继承该trait的类的父类2 3 class MyUtil {4 def printMessage(msg: String) = println(msg)5 }6 7 trait Logger extends MyUtil {8 def log(msg: String) = printMessage("log: " + msg)9 } 10 11 class Person(val name: String) extends Logger { 12 def sayHello { 13 log("Hi, I'm " + name) 14 printMessage("Hi, I'm " + name) 15 } 16 }
转载于:https://www.cnblogs.com/cxhfuujust/p/9908949.html
scala学习笔记-面向对象编程之Trait相关推荐
- Spark基础-scala学习(三、Trait)
面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...
- Scala 学习笔记
Scala 学习笔记 1 object func_exp { 2 println("Welcome to the Scala worksheet") //> Welcome ...
- Scala学习笔记04:内建控制结构
Scala学习笔记04:内建控制结构 scala提供的控制结构并不算多,因为在函数式编程中,可以自己开发出各种功能的控制结构,所以scala提供的原生控制结构仅仅够用为止. 1.if - 判断 if是 ...
- Scala学习笔记03:操作符
Scala学习笔记03:操作符 一.scala中操作符与方法的等价性 scala中操作符即方法.方法即操作符.scala中操作符其实是普通方法调用的另一种表现形式,运算符的使用其实就是隐含地调用对应的 ...
- Scala学习笔记02:数据类型、常量与变量
Scala学习笔记02:数据类型.常量与变量 一.数据类型 1.基本数据类型 Byte 字节型 Short 短整型 Int 整型 Long 长整型 Char 字符型 String 字符串 Float ...
- Scala学习笔记(三)
Scala学习笔记(三) 一.模式匹配 1. 简单模式匹配 2. 匹配类型 3. 守卫 4. 匹配样例类 5. 匹配数组 6. 匹配列表 7. 匹配元组 8. 变量声明中的模式匹配 8.1 获取数组中 ...
- Scala学习笔记(一)
Scala学习笔记(一) 一.Scala简介 二.Scala安装与配置 1. 安装JDK 2. 安装Scala SDK 3. 安装IDEA插件 三.Scala解释器 1. 启动Scala解释器 2. ...
- Scala学习笔记-环境搭建以及简单语法
关于环境的搭建,去官网下载JDK8和Scala的IDE就可以了,Scala的IDE是基于Eclipse的. 下面直接上代码: 这是项目目录: A是scala写的: package first impo ...
- Scala学习笔记-方便查找使用 为Spark学习打基础
Scala学习 注意 伊始 为什么是Scala 网课 环境 电脑环境安装 关于版本的声明 我的环境和版本 IDEA插件安装 IDEA关联Scala源码 基础部分1 文档注释和生成 字符串的三种输出 变 ...
最新文章
- 算法设计与分析课程的时间空间复杂度
- CentOS编译安装PHP 7.0
- python / 解决 pyinstaller 打包后运行时提示找不到模块的问题
- Springboot@PathVariable注解使用--请求路径占位符
- 2020年Deribit成交量达2110亿美元 同比增长82%
- C++之实现优先队列
- 从Python入门人工智能指南
- 《SAP快速入门》视频课程
- 倾斜摄影模型(.osgb)中心点位置的确定方法(SuperMap idesktop)
- cad批量打印快捷键_批量打印CAD图(无删减版)
- 面试官问:如何搭建测试环境?掌握这5种技能和知识就够了
- 每天学一个 Linux 命令(115):accton
- jbe 可以用来修改Java class的字节码,配合jd-gui 使用
- 神经系统疾病题库【1】
- 23-Travel旅游-签证
- 编译安装redis6.2.6
- 历史最全自然语言处理测评基准分享-数据集、基准(预训练)模型、语料库、排行榜
- dw在php图片滑动切换效果,超简单的图片左右切换滑动
- net mysql反斜杠怎么入库_MySQL中如何插入反斜杠,反斜杠被吃掉,反斜杠转义
- Nginx轮训tomcat服务器配置流程
热门文章
- python任务队列 http_基于Python开发的分布式任务队列:Celery
- html.partial mvc,MVC Html.Partial or Html.Action
- android sliding tab,android – 刷新SlidingTabLayout
- vs2012html图片,简单几步 实现vs2010对html5的支持
- 压缩文件夹_怎样压缩文件夹并发送
- mysql性能的介绍少_MySQL性能突然下降怎么回事 MySQL性能突然下降原因介绍
- 天体摇摆仪的工作原理
- 什么时候用redis_C++传参什么时候用引用, 什么时候用指针?
- 无法进入一个空框_win10电脑开机进入不了系统如何解决?
- django安装mysql_django+mysql安装和设置