Scala第八章节
章节目标
- 能够使用trait独立完成适配器, 模板方法, 职责链设计模式
- 能够独立叙述trait的构造机制
- 能够了解trait继承class的写法
- 能够独立完成程序员案例
1. 特质入门
1.1 概述
有些时候, 我们会遇到一些特定的需求, 即: 在不影响当前继承体系的情况下, 对某些类(或者某些对象)的功能进行加强, 例如: 有猴子类和大象类, 它们都有姓名, 年龄, 以及吃的功能, 但是部分的猴子经过马戏团的训练后, 学会了骑独轮车. 那骑独轮车这个功能就不能定义到父类(动物类)或者猴子类中, 而是应该定义到特质
中. 而Scala中的特质, 要用关键字trait
修饰.
1.2 特点
-
特质可以提高代码的复用性.
-
特质可以提高代码的扩展性和可维护性.
-
类与特质之间是继承关系, 只不过类与类之间只支持
单继承
, 但是类与特质之间,既可以单继承, 也可以多继承
. -
Scala的特质中可以有普通字段, 抽象字段, 普通方法, 抽象方法.
注意:
- 如果特质中只有抽象内容, 这样的特质叫: 瘦接口.
- 如果特质中既有抽象内容, 又有具体内容, 这样的特质叫: 富接口.
1.3 语法
定义特质
trait 特质名称 {
// 普通字段
// 抽象字段
// 普通方法
// 抽象方法
}
继承特质
class 类 extends 特质1 with 特质2 {
// 重写抽象字段
// 重写抽象方法
}
注意
- scala中不管是类还是特质, 继承关系用的都是
extends
关键字 - 如果要继承多个特质(trait),则特质名之间使用
with
关键字隔开
1.4 示例: 类继承单个特质
需求
- 创建一个Logger特质,添加
log(msg:String)
方法 - 创建一个ConsoleLogger类,继承Logger特质,实现log方法,打印消息
- 添加main方法,创建ConsoleLogger对象,调用log方法.
参考代码
//案例: Trait入门之类继承单个特质
object ClassDemo01 {
//1. 定义一个特质.
trait Logger {
def log(msg:String) //抽象方法
}
//2. 定义一个类, 继承特质.
class ConsoleLogger extends Logger {
override def log(msg: String): Unit = println(msg)
}
def main(args: Array[String]): Unit = {
//3. 调用类中的方法
val cl = new ConsoleLogger
cl.log("trait入门: 类继承单个特质")
}
}
1.5 示例: 类继承多个trait
需求
- 创建一个MessageSender特质,添加
send(msg:String)
方法 - 创建一个MessageReceiver特质,添加
receive()
方法 - 创建一个MessageWorker类, 继承这两个特质, 重写上述的两个方法
- 在main中测试,分别调用send方法、receive方法
参考代码
//案例: 类继承多个trait
object ClassDemo02 {
//1. 定义一个特质: MessageSender, 表示发送信息.
trait MessageSender {
def send(msg:String)
}
//2. 定义一个特质: MessageReceiver, 表示接收信息.
trait MessageReceiver {
def receive()
}
//3. 定义一个类MessageWorker, 继承两个特质.
class MessageWorker extends MessageSender with MessageReceiver {
override def send(msg: String): Unit = println("发送消息: " + msg)
override def receive(): Unit = println("消息已收到, 我很好, 谢谢!...")
}
//main方法, 作为程序的主入口
def main(args: Array[String]): Unit = {
//4. 调用类中的方法
val mw = new MessageWorker
mw.send("Hello, 你好啊!")
mw.receive()
}
}
1.6 示例: object继承trait
需求
- 创建一个Logger特质,添加
log(msg:String)
方法 - 创建一个Warning特质, 添加
warn(msg:String)
方法 - 创建一个单例对象ConsoleLogger,继承Logger和Warning特质, 重写特质中的抽象方法
- 编写main方法,调用单例对象ConsoleLogger的log和warn方法
参考代码
//案例: 演示object单例对象继承特质
object ClassDemo03 {
//1. 定义一个特质Logger, 添加log(msg:String)方法.
trait Logger{
def log(msg:String)
}
//2. 定义一个特质Warning, 添加warn(msg:String)方法.
trait Warning{
def warn(msg:String)
}
//3. 定义单例对象ConsoleLogger, 继承上述两个特质, 并重写两个方法.
object ConsoleLogger extends Logger with Warning{
override def log(msg: String): Unit = println("控制台日志信息: " + msg)
override def warn(msg: String): Unit = println("控制台警告信息: " + msg)
}
//main方法, 作为程序的入口
def main(args: Array[String]): Unit = {
//4. 调用ConsoleLogger单例对象中的两个方法.
ConsoleLogger.log("我是一条普通日志信息!")
ConsoleLogger.warn("我是一条警告日志信息!")
}
}
1.7 示例: 演示trait中的成员
需求
- 定义一个特质Hero, 添加具体字段name(姓名), 抽象字段arms(武器), 具体方法eat(), 抽象方法toWar()
- 定义一个类Generals, 继承Hero特质, 重写其中所有的抽象成员.
- 在main方法中, 创建Generals类的对象, 调用其中的成员.
参考代码
//案例: 演示特质中的成员
object ClassDemo04 {
//1. 定义一个特质Hero
trait Hero{
var name = "" //具体字段
var arms:String //抽象字段
//具体方法