trait多继承

3 阅读2分钟

(一)、多个trait的加载顺序

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

scala
 体验AI代码助手
 代码解读
复制代码
/**
 * 多继承时,构造器调用顺序
 * 1.先父后子。先调用父类构造器,在调用子类构造器
 * 2.有多个父类,从左到右的顺序去调用构造器
 */
object class20 {

  trait A {
      println("traitA")
    }


  trait B {
    println("traitB")
  }

  trait C {
    println("traitC")
  }

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

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

}

(二)、多层trait的加载顺序

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

scala
 体验AI代码助手
 代码解读
复制代码
/**
 * 多继承时,构造器调用顺序
 * 1.先父后子。先调用父类构造器,在调用子类构造器
 * 2.有多个父类,从左到右的顺序去调用构造器
 */
object class21 {

  trait A {
      println("traitA")
    }

  trait BB {
    println("traitBB")
  }


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

  trait CC {
    println("traitCC")
  }

  trait C extends CC{
    println("traitC")
  }

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

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

}

(三)、空指针异常

scala
 体验AI代码助手
 代码解读
复制代码
import java.io.FileWriter

/**
 *空指针异常
 *
 * 目标:实现日志类,可以把一些文本信息写入指定的文件中
 *
 */
object class23 {

  trait Log {
    // 抽象属性:文件名
    var fileName:String

    println(s"${fileName}")
    //具体属性
    // lazy 懒加载
    lazy val fileWriter:FileWriter = new FileWriter(fileName)

    def writerLog(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.writerLog("2025-11-19:下午,天气晴朗")

  }

}

(四)、trait与类的区别

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

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

scala
 体验AI代码助手
 代码解读
复制代码
/**
 * trait 和 抽象类class的区别?
 *
 * 1.相同点。
 *    可以被继承,extends
 *    属性和方法:抽象属性,具体属性,抽象方法,具体方法
 *    都不能被实例化。不能new
 *
 * 2.不同点。
 *    trait 支持多继承:抽象类不能多继承;
 *
 */
object class22 {

  trait A {
      println("trait A")
    }

  trait B {
    println("trait A")
  }

  class C extends A with B {
  }

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

}