I'm wanting to do something like this:
class A (var updateCount: Int) {
}
class B (val name: String, var updateCount: Int) extends A(updateCount) {
def inc(): Unit = {
updateCount = updateCount + 1
}
}
var b = new B("a", 10)
println(b.name)
println(b.updateCount)
b.updateCount = 9999
b.inc
println(b.updateCount)
but the compiler doesn't like it.
(fragment of extend.scala):5: error: erro开发者_Python百科r overriding variable updateCount in class A of type Int;
variable updateCount needs `override' modifier
class B (val name: String, var updateCount: Int) extends A(updateCount) {
Adding override on updateCount doesn't work either. What's the clean way to do this?
You don't need to declare the var
in the subclass constructor signature:
class B (val name: String, /* note no var */ updateCount: Int) extends A(updateCount) {
//...
}
This also extends to classes with val
s in their constructors also:
scala> class C(val i: Int)
defined class C
scala> class D(j: Int) extends C(j)
defined class D
You need to avoid having the identifier declared for B
shadowing the identifier declared for A
. The easiest way to do that is to chose a different name. If, however, you really, really don't want to do that, here is an alternative:
class B (val name: String, updateCount: Int) extends A(updateCount) {
self: A =>
def inc(): Unit = {
self.updateCount = self.updateCount + 1
}
}
And, by the way, drop the var
from B declaration.
When you use the var
keyword in the parameters, this makes the value passed in be a new var
in the class. When you don't do that, it makes it a constructor parameter (only), and you use it's value for the var
by passing it to the constructor. So the example that people have given
class B(val name:String, updateCount:Int) extends A(updateCount)
is correct.
However, scala makes constructor parameters directly available to the methods in the class (I'm not sure why), so if you use the same name you will find that your code fails to compile with the error reassignment to val
when you try to reassign the "var". For example in the following snippet, the immutable constructor parameter shadows the inherited var
and so you can't assign to the parameter.
class B (val name: String, updateCount: Int) extends A(updateCount) {
def inc(): Unit = {
updateCount = updateCount + 1
}
}
As others mention, your constructor param in B is shadowing the superclass' version. Here's the code that works and doesn't require self-type:
class A (var updateCount: Int) {
}
class B (val name: String, uc: Int) extends A(uc) {
def inc(): Unit = {
updateCount = updateCount + 1
}
}
精彩评论