简单的Scala getter / setter覆盖 [英] Simple Scala getter/setter override
问题描述
假设我们有一个带有'name'属性的类:
Let's say we have a class with a 'name' property:
class SuperFoo(var name: String)
如果我想覆盖这个,例如在呼叫周围加一些锁定:
If I wish to override this, to eg add some locking around the calls:
class SubFoo(n: String) extends SuperFoo(n) {
val lock = new ReentrantLock
override def name(): String =
{
lock.lock
try {
super.name
} finally {
lock.unlock
}
}
override def name_=(arg: String): Unit = {
lock.lock
try {
super.name = arg
} finally {
lock.unlock
}
}
}
以上产生编译错误:
super may be not be used on variable name
任何想法如何正确实现这个? (即覆盖getter& setter以在它们周围添加锁定)。谢谢!
Any ideas how to correctly implement this? (i.e. override the getter & setter to add locking around them). Thanks!
推荐答案
这里你需要直接引用超类setter / getter。通常你应该这样写:
Here you need to refer directly to the super class setter/getter. Normally you should write something like:
class SubFoo(n: String) extends SuperFoo(n) {
val lock = new ReentrantLock
override def name(): String =
{
lock.lock
try {
super.name()
} finally {
lock.unlock
}
}
override def name_=(arg: String): Unit = {
lock.lock
try {
super.name_=(arg)
} finally {
lock.unlock
}
}
}
但是,如果setter编译没有任何问题,则getter不会,因为编译器会将其视为 super.name.apply( )
(字符串可以通过隐式转换获得此方法)。
However, if the setter will compile without any problem, the getter won't because the compiler will view it as super.name.apply()
(Strings can get this method through implicit conversions).
我看到几个选项:
- 赞成合成而不是继承(经典)。
- 更改变量名,将其设为私有并在超类中写入访问器(见下文) )。
- Res ort to reflection / manual name umangling voodoo。
我会选择#1选项,但这里是选项#2的代码:
I'll go for option #1, but here is code for option #2:
class SuperFoo( private var nameVar: String) {
def name: String = nameVar
def name_=(arg: String): Unit = nameVar = arg
}
class SubFoo(n: String) extends SuperFoo(n) {
val lock = new ReentrantLock
override def name(): String =
{
lock.lock
try {
super.name
} finally {
lock.unlock
}
}
override def name_=(arg: String): Unit = {
lock.lock
try {
super.name = arg
} finally {
lock.unlock
}
}
}
编辑:这是选项#1的可行实现:
EDIT: Here is a workable implementation of option #1:
trait Foo {
def name: String
def name_=(arg: String): Unit
}
class SimpleFoo( var name: String) extends Foo
class LockedFoo(foo: Foo) extends Foo {
val lock = new ReentrantLock
def name(): String =
{
lock.lock
try {
foo.name
} finally {
lock.unlock
}
}
def name_=(arg: String): Unit = {
lock.lock
try {
foo.name = arg
} finally {
lock.unlock
}
}
}
这篇关于简单的Scala getter / setter覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!