Reputation: 886
Suppose I would like to extend class C
, getting SubC
.
Now I would like to access the variable c
in SubC
as presented in the example below in the method printC
.
The following does not work, as calling printC
on a SubC
instance will print SubC
's c
and not C
's c
(I guess I could have picked better names...)
class C(protected var c : Int) {
def update(n : Int) {
c = n
}
}
class SubC(c: Int) extends C(c) {
def printC : Unit = {
println(c)
}
}
object Main {
def main(args: Array[String]) {
val subC = new SubC(1)
subC.update(3)
subC.printC // prints 1
}
}
A possible (but undesirable) solution would be:
class SubC(cc: Int) extends C(cc) {
def printC = {
println(c)
}
}
This works but it introduces a new (and unneeded) identifier cc
into scope.
Is there a better (cleaner) way of doing this?
PS: To put the example above into some context. What I actually want to do is to augment C
with some traits without introducing new identifiers into scope.
Upvotes: 2
Views: 262
Reputation: 297185
Use self types:
class SubC(c: Int) extends C(c) {
self: C =>
def printC : Unit = {
println(self.c)
}
}
Upvotes: 2
Reputation: 13196
This is probably the best way to augment C with traits without introducing new identifiers in scope:
class C(protected var c : Int) {
def update(n : Int) {
c = n
}
}
trait CanPrintC {
self: C =>
def printC : Unit = {
println(c)
}
}
class SubC(c: Int) extends C(c) with CanPrintC
object Main {
def main(args: Array[String]) {
val subC = new SubC(1)
subC.update(3)
subC.printC // prints 3
}
}
Upvotes: 9