简单的Scala getter/setter覆盖

Nik*_*aos 9 getter setter inheritance scala properties

假设我们有一个带有'name'属性的类:

class SuperFoo(var name: String) 
Run Code Online (Sandbox Code Playgroud)

如果我希望覆盖它,例如在调用周围添加一些锁定:

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

以上产生了编译错误:

super may be not be used on variable name 
Run Code Online (Sandbox Code Playgroud)

任何想法如何正确实现这一点?(即覆盖getter和setter以在它们周围添加锁定).谢谢!

par*_*tic 6

在这里你需要直接引用超类setter/getter.通常你应该写一些类似的东西:

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果setter编译没有任何问题,getter将不会因为编译器将其视为super.name.apply()(字符串可以通过隐式转换获得此方法).

我看到几个选项:

  1. 赞成组合而不是继承(经典).
  2. 更改变量名称,使其成为私有,并在超类中编写访问器(见下文).
  3. 度假胜地反映/手工名称umangling伏都教.

我将选择#1选项,但这里是选项#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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是选项#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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)