Scala用var替代了一个非抽象的def
在Scala我可以做到这一点:
trait SomeTrait { protected def foo: String } class Wibble extends SomeTrait { protected var foo = "Hello" } 但是我不能做同样的事情,我为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" } 为什么我不能这样做? 编辑:在scala-users邮件列表上进行交谈后,我有raised this in trac 解决方法
在Scala中,当您编写一个var foo时,Scala编译器会自动为其生成一个setter(称为foo_ =)和一个getter(称为foo),并将该字段设置为private(如果您反编译一个具有javap的’public’Scala字段的类).这就是’foo_ =不覆盖任何东西’错误的方法.在你的特质中,你没有定义一个foo_ =方法,而对于一个public field setter和getter来说,它们总是成对的.
如果您不在trait(即抽象方法)中提供默认值,则不需要override关键字.因此,在第一个例子中,getter覆盖了抽象方法和setter …它只是在那里.编译器不会抱怨.但是,当您在trait中提供方法的实际实现时,您需要在覆盖时特别写入override关键字.当编写protected var foo时,您没有为getter指定override关键字,并且在写入覆盖保护的var foo时,还向编译器指出了要覆盖foo_ =的方法,但trait没有这样的方法. 另外,逻辑上你不能真正地用var覆盖def(考虑到一个严格的覆盖视图,像上一段). def在逻辑上是一个函数(你给它一些输入,它产生一个输出). var类似于no-arg函数,但也支持将其值设置为其他值,这是函数不支持的操作.相反,如果你把它改成val,那就行了.这就像一个总是产生相同(缓存)结果的函数. 如果你想对var有类似的行为,你可以这样做(通过使用显式的setter和getter): class Wibble extends SomeTrait { private var bar = "Hello" override protected def foo = bar protected def foo_=(v: String) { bar = v} } 现在你可以做任何事情你可以做一个var :). val x = new Wibble println(x.foo) // yields "Hello" x.foo = "Hello again" println(x.foo) // yields "Hello again" (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |