trait
- 特质: trait
- trait是关键字,identified 表示一个合法的标记。
- 作用: 类似于抽象类 定义抽象属性 方法
- 让其他的子类去实现
- 特点:可以实现多继承
- 作用: 封装成员和方法,供其他类来实现。它可以实现多继承!
一、实现单个特质
用一个类去实现单个特质
trait A {
var name:String;
}
class Class1 extends A {
var name:String = "Class1"
}
def main(args: Array[String]): Unit = {
val class1 = new Class1()
println(class1.name)
}
二、实现多个特质
类名 extends 特质1 with 特质2 with 特质3 其中多个特质的顺序可以交换。
trait A {
var name:String; // __抽象__属性
def sayA():Unit = { // __具体__方法
println("sayA")
}
}
trait B {
var age:Int
}
class Class1 extends A with B {
var name:String = "Class1"
var age:Int = 4
}
def main(args: Array[String]): Unit = {
val class1 = new Class1()
class1.sayA
println(class1.name)
println(class1.age)
}
三、多继承
① 有多个父类,从左到右的顺序去调用构造器
问: 一个类实现了多个特质之后,所涉及的多个构造器的执行顺序如何确定?
答: 如果有多个父类,则按照从左到右的顺序调用。
trait A {
println("trait A")
}
trait B {
println("trait B")
}
trait C {
println("trait C")
}
class Class1 extends B with A with C{
println("class 1.....")
}
def main(args: Array[String]): Unit = {
new Class1
}
② 先父后子。 先调用父类构造器,再调用子类构造器
先执行父类中的构造器,再执行子类的构造器:如果trait1也有自己的父类,要先执行父类构造器
trait A {
println("trait A")
}
trait BB {
println("trait BB")
}
trait B extends BB {
println("trait B")
}
trait CC {
println("trait CC")
}
trait C extends CC {
println("trait C")
}
class Class1 extends B with A with C{
println("class 1.....")
}
def main(args: Array[String]): Unit = {
new Class1
}
四、class 与 trait 的区别
1. 相同点
- 可以被继承,extends
- 属性和方法:抽象属性,具体属性,抽象方法
- 都不能被实例化,不能new
2.不同点
- trait 支持多继承;抽象类不能多继承
trait A {
println("trait A")
}
trait B {
println("trait B")
}
class C extends A with B{
}
def main(args: Array[String]): Unit = {
new C()
}
五、空指针异常
**目标:**实现日志类 可以把一些文本信息写入指定的文件中
trait Log {
// 文件名:抽象属性
var fileName:String
// 具体属性
// lazy 懒加载 懒
// 将 fileWriter 改为 lazy val 或 def,确保在 fileName 初始化后使用
lazy val fileWriter:FileWriter = new FileWriter(fileName)
def writeLog(msg:String):Unit = {
fileWriter.write(msg)
fileWriter.close()
}
}
class TextLog extends Log {
var fileName:String = "text01.log"
}
def main(args: Array[String]): Unit = {
val textLog = new TextLog()
textLog.writeLog("2025-11-19; 下午 天气晴朗")
}