scala 中 trait 中使用的抽象值有什么问题吗? [英] Is there something wrong with an abstract value used in trait in scala?
问题描述
我有
trait Invoker {
val method: Method
}
Intellij IDEA 代码检查警告我特征中使用了抽象值".一切都编译得很好.在特征中具有抽象值有什么问题吗?如果是这样,我应该如何指定 trait 的所有扩展器都必须定义一个方法属性?
Intellij IDEA code inspection is warning me that "Abstract value used in trait". Everything compiles fine. Is there something wrong with having an abstract value in a trait? If so, how should I specify that all extenders of the trait must define a method property?
推荐答案
这意味着以下奇怪之处:</p>
What is meant by this is the following weirdness:
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
for AnyRef
)在 C
中.(def
声明会立即重新引用.)
So, as you can see i
is initialised to it default value (null
for AnyRef
) before it is finally overridden by the constructor in C
. (def
declarations are re-referenced immediately.)
为了避免这种情况,如果可能的话,必须将 val
初始化放在构造函数的开头.
To avoid this one would have to put the val
initialisations to the beginning of the constructor, if possible.
在以下情况下的其他奇怪之处(以及如何解决它)
考虑
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
现在我们似乎不走运;看起来好像我们没有机会在我们的超类 D
尝试之前初始化 val i
and def j
打印它们.为了解决这个问题,我们必须使用早期定义(§5.1.6 Scala 参考):
Now we seem to be out of luck; it looks as if there is no chance for us to initialise val i
and def j
before our superclass D
tries to print them.
In order to solve this problem, we must use Early definitions (§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 中 trait 中使用的抽象值有什么问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!