(一) trait的定义与作用
Scala没有Java中接口的概念,所以Scala的trait就类比Java中的接口
trait是关键字,identified 表示一个合法的标记。
作用:封装成员和方法,供其他类来实现。它可以实现多继承!
(二)实现单个特质
package levelo3
object class010 {
trait A {
var name:String;
def sayA():Unit={
println("sayA")
}
}
class Class1 extends A {
var name:String="Class1"
}
def main(args: Array[String]): Unit = {
val class1=new Class1()
class1.sayA()
println(class1.name)
}
}
(三) 实现多个特质
格式:类名 extends 特质1 with 特质2 with 特质3 ,其中多个特质的顺序可以交换。
package levelo3
object class010 {
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)
}
}
多继承讲解
多继承时,构造器调用顺序
- 先父后子。先调用父类构造器,在调用子类构造器
- 有多个父类,从左到右的顺序去调用构造器
代码演示:
package levelo3
object class010 {
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)
}
}
结果:
先执行父类中的构造器,再执行子类的构造器:如果trait1也有自己的父类,要先执行父类构造器
package levelo3
object class011 {
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()
}
}
结果:
空指针异常
问题解决方法
方法1:懒加载
lazy val fileout = new PrintWriter(filename)
方法2:提前定义
val p = new {override val filename="p052.log"} with Person051
trait与类的区别
相同点:类和trait都可以定义成员变量(抽象,具体);继承时都使用extends关键字;
不同点:trait的构造器不能带参数;trait支持多继承; 代码、
package levelo3
import java.io.FileWriter
object class012 {
trait Log {
var fileName:String
println(s"${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:下午,天气晴朗")
}
}
结果: