多繼承問題:
object LoadIssueDemo extends App {
import java.io.PrintWriter
trait Logger {
def log(msg: String): Unit
}
trait FileLogger extends Logger {
val fileName: String
val fileOutput = new PrintWriter(fileName: String)
fileOutput.println("#")
def log(msg: String): Unit = {
fileOutput.print(msg)
fileOutput.flush()
}
}
class Person
class Student(var name: String) extends Person with FileLogger {
override val fileName: String = "file.log"
}
new Student("Win").log("trait demo")
}
運行結果:
原因:fileName還未初始化,就被方法調用。
解決方法:
1. 提前定義 (代碼不夠優雅)
object PreDefineDemo extends App{ import java.io.PrintWriter trait Logger{ def log(msg: String): Unit } trait FileLogger extends Logger { val fileName: String val fileOutput = new PrintWriter(fileName: String) fileOutput.println("#") def log(msg: String): Unit ={ fileOutput.print(msg) fileOutput.flush() } } class Person class Student(var name: String) extends Person with FileLogger{ override val fileName: String = "file.log" } new { override val fileName: String = "file.log"} with Student("Win").log("trait demo") }
2. 懶加載(推薦)
object LazyLoadDemo extends App{ import java.io.PrintWriter trait Logger{ def log(msg: String): Unit } trait FileLogger extends Logger { val fileName: String lazy val fileOutput = new PrintWriter(fileName: String) def log(msg: String): Unit ={ fileOutput.print(msg) fileOutput.flush() } } class Person class Student(var name: String) extends Person with FileLogger{ override val fileName: String = "file.log" } val s = new Student("Win") s.log("#") s.log("Lazy demo") }