ade*_*rtc 2 inheritance scala multiple-inheritance traits
所以我正在为不耐烦的书阅读Scala,它使用的一个例子是一个Logger基本上打印String到某个流的特征.在该实例中,它具有性状ConsoleLogger(延伸Logger),该打印消息出去stdout和ShortLogger(也延伸Logger),其简单地截断字符串,如果该长度过长.要改变ShortLogger书籍的最大长度,建议使用匿名子类,如:
val acct = new SavingsAccount with ConsoleLogger with ShortLogger {
val maxLength = 20
}
Run Code Online (Sandbox Code Playgroud)
ShortLogger具有抽象maxLength: Int字段的特征在哪里SavingsAccount定义为
class SavingsAccount extends Account with Logged { ... }
Run Code Online (Sandbox Code Playgroud)
这对我有意义(有点).我假设施工顺序是:
Logger首先构建(因为它是一个超级特征ConsoleLogger),ConsoleLoggerShortLoggerAccount SavingsAccount. maxLength = 20.然而,在本书的后面,它给出了一个新的Logger子特征:
trait FileLogger extends Logger {
val filename: String
val out = new PrintStream(filename)
def log(msg: String) { out.println(msg); out.flush() }
}
val acct = new SavingsAccont with FileLogger {
val filename = "myapp.log" // Does not work
}
Run Code Online (Sandbox Code Playgroud)
它说由于施工顺序它不起作用.他们建议修改:
val acct = new {
val filename: "myapp.log"
} with SavingsAccount with FileLogger
Run Code Online (Sandbox Code Playgroud)
但是,这个定义似乎与上面的定义相似maxLength,所以我在上面的例子和底部例子之间缺少什么?
你的施工顺序是完全错误的.:-)
要构建的第一件事是课程,然后你从左到右经历这些特征.这有点复杂 - 有线性化规则处理多次遗传的特征,但这就是它.
所以:
现在,问你的问题:
val acct = new SavingsAccont with FileLogger {
val filename = "myapp.log" // Does not work
}
val acct = new {
val filename: "myapp.log"
} with SavingsAccount with FileLogger
Run Code Online (Sandbox Code Playgroud)
请注意,代码块在第二个示例中排在第一位.这就是所谓的早期初始化,它的作用是在其他任何事情之前应用该初始化.