构造器调用顺序

30 阅读1分钟

多继承时,构造器调用顺序

1.先父后子。先调用父类构造器,在调用子类构造器

2.如果有多个父类,从左到右的顺序去调用构造器

eg:

object class16 {
  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()
  }
}

当父类构造器有父类时,先调用最高的父类依次往下从左到右调用

object class16 {
  trait A {
    println("trait A")
  }
  
  trait BB {//父类构造器B的父类
    println("trait BB")
  }
  
  trait B extends BB{
    println("trait B")
  }
  
  trait CC {//父类构造器C的父类
    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()
  }
}

输出结果为

trait BB
trait B
trait A
trait CC
trait C
class 1

理论知识:

trait 和 抽象类class的区别

1.相同点

可以被继承,extends

属性和方法:抽象属性,具体属性,抽象方法,具体方法

都不能被实例化。不能new

2.不同点

trait 支持多继承,抽象类不能多继承

eg:

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

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

    def writeLog (msg:String):Unit = {
      fileWriter.write(msg)
      fileWriter.close()
    }
  }
  //先执行父类构造器,所以报错
  class TextLog extends Log {
    var fileName:String = "text.log"
  }
  def main(args: Array[String]): Unit = {
    val textLog = new TextLog()
    textLog.writeLog("2025-11-19:下午,天气晴朗")
  }
}