我有
trait Invoker {
val method: Method
}
Intellij IDEA 代码检查警告我“特征中使用的抽象值”。一切都编译得很好。在特征中具有抽象值有什么问题吗?如果是这样,我应该如何指定 trait 的所有扩展器都必须定义一个方法属性?
最佳答案
这意味着以下奇怪之处:
trait A {
val i: String
def j: String
}
class C extends A {
println ("val i = " + i)
println ("def j = " + j)
val i = "i"
def j = "j"
}
val c = new C
// prints
// val i = null
// def j = j
所以,正如你所看到的
i
在它最终被 null
中的构造函数覆盖之前被初始化为它的默认值( AnyRef
for C
) . ( def
声明会立即重新引用。)为避免这种情况,必须输入
val
如果可能,初始化到构造函数的开头。在以下情况下额外的怪异(以及如何解决它)
考虑
trait A {
val i: String
def j: String
}
abstract class D extends A {
println ("val i = " + i)
println ("def j = " + j)
}
class C extends D {
val i = "i"
def j = "j"
}
val c = new C
// prints
// val i = null
// def j = null
现在我们似乎不走运;看起来好像我们没有机会初始化
val i
和 def j
在我们的父类(super class)之前 D
尝试打印它们。为了解决这个问题,我们必须使用早期定义(§5.1.6 Scala reference):
class C extends {
val i = "i"
def j = "j"
} with D
val c = new C
// prints
// val i = i
// def j = j
它有效!
关于scala - Scala 中 trait 中使用的抽象值有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7846119/