简单的Scala getter / setter覆盖 [英] Simple Scala getter/setter override

查看:136
本文介绍了简单的Scala getter / setter覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个带有'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).

我看到几个选项:


  1. 赞成合成而不是继承(经典)。

  2. 更改变量名,将其设为私有并在超类中写入访问器(见下文) )。

  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆