In Scala, when you write a var foo
, the Scala compiler automatically generates a setter (called foo_=
) and a getter (called foo
) for it, and sets the field as private (you'll see it as private if you decompile a class having 'public' Scala fields with javap
). That's what the 'method foo_= overrides nothing' error means. In your trait you haven't defined a foo_=
method, and for a public field setter and getters always come in pairs.
If you do not provide a default value in the trait (i.e. abstract method), then the override
keyword is not necessary. Therefore, in your first example, the getter overrides the abstract method and the setter... it just is there. The compiler doesn't complain. But when you provide an actual implementation of the method in the trait, you need to specifically write the override
keyword when overriding. When writing protected var foo
, you haven't specified the override
keyword for the getter and when writing override protected var foo
, you have also indicated to the compiler that method foo_=
is to be overridden, but the trait has no such method.
Also, logically you cannot really override a def
with a var
(considering a strict view of overriding, like in the previous paragraph). A def
is logically a function (you give it some input, it produces an output). A var
is similar to a no-arg function, but also supports setting its value to something else, an operation which is not supported by a function. Instead, if you would change it to a val
, it would be OK. It's like a function that always produces the same (cached) result.
If you want to have similar behaviour to a var
you could do something like this (by having explicit setter and getters):
class Wibble extends SomeTrait {
private var bar = "Hello"
override protected def foo = bar
protected def foo_=(v: String) { bar = v}
}
Now you can do anything you could do with a var :).
val x = new Wibble
println(x.foo) // yields "Hello"
x.foo = "Hello again"
println(x.foo) // yields "Hello again"
-- Flaviu Cipcigan