(二十二)trait-多继承详解

0 阅读2分钟

(一)多个trait的加载顺序

  • 如果有多个父类,则按照从左到右的顺序调用。
  • 图例

屏幕截图 2025-11-26 081333.png

  • 代码如下
package level02
object class25 {
  trait A {
    println("A")
  }
  trait B {
    println("B")
  }

  class Class1 extends A with B {
    println("Class1")
  }

  def main(args: Array[String]): Unit = {
    new Class1()
  }
}

特质:trait

  • 实现多继承后,注意观察父类中的代码块的执行顺序
    1. 先父后子
    1. 有多个父类,按书写顺序从左向右执行!

( 二)多层trait的加载顺序

  • 先执行父类中的构造器,再执行子类的构造器:如果trait1也有自己的父类,要先执行父类构造器
  • 图例

屏幕截图 2025-11-26 083720.png

package level02
object class26 {
  trait A {
    println("A")
  }

  trait BB {
    println("BB")
  }
  trait B extends BB {
    println("B")
  }

  // trait C {
  //   println("C")
  // }

  class Class1 extends B with A {
    println("Class1")
  }

  def main(args: Array[String]): Unit = {
    new Class1()
  }
}

(三)空指针异常

package level02

import java.io.FileWriter

/*
* 演示一个程序错误(原代码因初始化顺序导致空指针,此处修正)
*/
object class27 {
  // 在文件中写入日志
  trait FileLogger {
    // 抽象属性:文件名
    val filename: String
    // 延迟初始化fileWriter,避免依赖未赋值的filename
    lazy val fileWriter: FileWriter = new FileWriter(filename, true)

    def writeLog(msg: String): Unit = {
      fileWriter.write(msg)
      fileWriter.close()
    }
  }

  class MyFileLogger extends FileLogger {
    val filename = "11-26.log"
  }

  def main(args: Array[String]): Unit = {
    val fileLogger = new MyFileLogger()
    fileLogger.writeLog("今天上午上scala课程")
  }
}

问题解决

  • 方法1:懒加载
  • 方法2:提前定义

(四)trait与类的区别

相同点:类和trait都可以定义成员变量(抽象,具体);继承时都使用extends关键字;

不同点:trait的构造器不能带参数;trait支持多继承;

package level02

import java.io.FileWriter

/*
* 演示一个程序错误
*/
object class28 {
  // 在文件中写入日志
  trait FileLogger {
    println(2)
    // 抽象属性:文件名
    val filename:String

    lazy val fileWriter = new FileWriter(filename, true)
    def writeLog(msg:String):Unit = {
      fileWriter.write(msg)
      fileWriter.close()
    }
  }

  class MyFileLogger extends FileLogger{
    println(1)
    val filename = "11-28.log"
  }

  def main(args: Array[String]): Unit = {
    val fileLogger = new MyFileLogger()
    fileLogger.writeLog("今天上午上scala课程")
  }
}