在Scala我可以这样做:
trait SomeTrait {
protected def foo: String
}
class Wibble extends SomeTrait {
protected var foo = "Hello"
}
Run Code Online (Sandbox Code Playgroud)
但我不能做同样的事情,我提供了默认定义 foo
trait SomeTrait {
protected def foo: String = "World"
}
class Wibble extends SomeTrait {
protected var foo = "Hello" //complains about lack of override modifier
override protected var foo = "Hello" //complains "method foo_ overrides nothing"
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能这样做?
编辑:在scala-users邮件列表上进行对话后,我在trac中提出了这个问题
Fla*_*gan 21
在Scala中,当你编写一个时var foo,Scala编译器自动为它生成一个setter(被叫foo_=)和一个getter(被调用foo),并将该字段设置为private(如果你反编译一个有'public'的类,你会看到它是私有的Scala字段与javap).这就是'方法foo_ =无所事事'错误意味着什么.在你的特质中,你还没有定义一个foo_=方法,对于公共字段设置器和getter 总是成对出现.
如果您没有在特征中提供默认值(即抽象方法),则override不需要关键字.因此,在您的第一个示例中,getter重写了抽象方法和setter ......它就在那里.编译器没有抱怨.但是当您在特征中提供方法的实际实现时,您需要override在覆盖时专门编写关键字.在写入时protected var foo,您没有override为getter 指定关键字,在编写时override protected var foo,您还向编译器指示foo_=要覆盖方法,但是trait没有这样的方法.
此外,从逻辑上讲,你真的不能重写def了var(考虑覆盖,像前一段的严格的观点).A def在逻辑上是一个函数(你给它一些输入,它产生一个输出).A var类似于无参数函数,但也支持将其值设置为其他函数,这是函数不支持的操作.相反,如果您将其更改为a val,那就没问题.它就像一个总是产生相同(缓存)结果的函数.
如果你想要有类似的行为,var你可以做这样的事情(通过明确的setter和getter):
class Wibble extends SomeTrait {
private var bar = "Hello"
override protected def foo = bar
protected def foo_=(v: String) { bar = v}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以用var :)做任何事情.
val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6170 次 |
| 最近记录: |