trait的基本使用2

42 阅读1分钟

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

  1. 先父后子。先调用父类构造器再调用子类构造器。
  2. 有多个父类,从左到右的顺序去调用构造器

基本代码

/*
*多继承时,构造器调用顺序。
*1. 先父后子。先调用父类构造器再调用子类构造器。
*2. 有多个父类,从左到右的顺序去调用构造器。
 */


object class25 {

  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("class1.....")
  }

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

此代码的输出结果

trait BB、trait B、trait A、trait CC、trait C、class1.....

BB是B的父类,CC是C的父类,A,B,C是class1的父类

trait和抽象类class的区别

相同点

  1. 可以被继承,extends
  2. 属性和方法:抽象属性,具体属性,抽象方法,具体方法
  3. 都不能实例化。不能被new

不同点

trait支持多继承;抽象不能多继承。

空指针异常

使用关键词:lazy

基本代码

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


object class26 {

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

    //具体属性
    // 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="text01.log"
  }

  def main(args: Array[String]): Unit = {
    val textlog=new TextLog()
    textlog
      .writeLog("2025-11-19:下午,天气晴朗")
  }
}