trait-多继承

9 阅读2分钟

多个trait加载顺序

package level2

object Sc79 {
  trait A {

    println("A")
  }


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

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

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

多层trait加载顺序

package level2

object Sc79 {
  trait A {

    println("A")
  }


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

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

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

空指针异常

package level2

import java.io.FileWriter

/*
 * 演示一个程序错误
 */
object Sc80 {
  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课程")
  }
}

trait与抽象类的区别

package level2

import java.io.FileWriter

/*
 * 演示一个程序错误
 */
object Sc81 {
  // 伴生对象中测试私有成员访问
  object Person {
    def test(p: Person): Unit = {
      // private修饰的成员,在伴生对象中可访问
      println(p.password)
      // private[this]修饰的成员,在伴生对象中无法访问
      // println(p.money)
    }
  }

  // 定义Person类,演示不同访问修饰符
  class Person() {
    // 公有成员(默认访问权限)
    var name: String = "xxx"
    // 受保护成员:子类可访问,外部不可访问
    protected var birthday: String = "2000-10-10"
    // 私有成员:仅类内部、伴生对象可访问
    private var password: String = "123456"
    // 对象私有成员:仅当前实例可访问,同类其他实例/伴生对象均不可访问
    private[this] var money: Int = 100

    // 类内部可访问对象私有成员
    def t(): Unit = {
      println(money)
    }
  }

  // 子类Son继承Person
  class Son extends Person() {
    // 子类可访问protected成员
    println(birthday)
    // 子类无法访问private成员
    // println(password)
  }

  // 主方法测试
  def main(args: Array[String]): Unit = {
    val p1 = new Person()
    // 外部可访问公有成员
    println(p1.name)
    // 外部无法访问protected成员
    // println(p1.birthday)

    // 创建子类实例,触发子类中protected成员的访问
    new Son()

    // 伴生对象访问Person的private成员
    Person.test(p1)
  }
}