En Scala, cuando se escribe un var foo
, el compilador Scala genera automáticamente un colocador (llamado foo_=
) y un captador (llamado foo
) para él, y establece el campo como privado (lo verá como privado si descompila una clase que tiene campos Scala 'públicos' con javap
). Eso es lo que significa el error "método foo_ = anula nada". En su rasgo no ha definido un método foo_=
, y para un setter de campo público y captadores siempre vienen en pares.
Si no proporciona un valor predeterminado en el rasgo (es decir, el método abstracto), la palabra clave override
no es necesaria. Por lo tanto, en su primer ejemplo, el getter anula el método abstracto y el setter ... simplemente está allí. El compilador no se queja. Pero cuando proporciona una implementación real del método en el rasgo, debe escribir específicamente la palabra clave override
al anular. Al escribir protected var foo
, no ha especificado la palabra clave override
para el captador y al escribir override protected var foo
, también ha indicado al compilador que el método foo_=
debe anularse, pero el rasgo no tiene dicho método.
Además, lógicamente no se puede anular realmente un def
con un (teniendo en cuenta una visión estricta de anulación, como en el párrafo anterior). A def
es lógicamente una función (le da algo de entrada, produce una salida). Un var
es similar a una función no-arg, pero también admite establecer su valor en otra cosa, una operación que no es compatible con una función. En cambio, si lo cambiara a val
, estaría bien. Es como una función que siempre produce el mismo resultado (en caché).
Si usted quiere tener un comportamiento similar a un var
se podría hacer algo como esto (por tener colocador explícita y getters):
class Wibble extends SomeTrait {
private var bar = "Hello"
override protected def foo = bar
protected def foo_=(v: String) { bar = v}
}
Ahora se puede hacer cualquier cosa que podría hacer con un :) var.
val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"
Lo siento, he cometido un error: el método de rasgo original también debería haber sido protegido. No estoy seguro de estar de acuerdo contigo acerca de que lógicamente no se puede anular una 'definición' con una 'var'. Todo lo que mi 'def' dice es que espero que haya un acceso llamado' foo' que devuelve un String - declarar que 'var' es una implementación de este –
Creo que estoy de acuerdo contigo. Estaba pensando en anularlo como una noción más estricta cuando escribí la respuesta. Editaré la respuesta y proporcionaré una solución viable :). –
Es una lástima que no haya una sintaxis 'anular def como var' –