2012-12-28 13 views
9

は、我々は「名前」プロパティを持つクラスを持っているとしましょう:シンプルScalaのゲッター/セッターのオーバーライド

class SuperFoo(var name: String) 

私はこれを無効にしたい場合は、通話の周りにいくつかのロックを追加し、たとえばする:

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 &セッターをオーバーライドしてロックを追加します)。ありがとう!

+0

コンパイラは私が変数をオーバーライドしていると思うようです:getterからsuper.nameステートメントを削除した場合、このエラーメッセージが表示されます: "タイプStringのクラスSuperFooでの変数名のオーバーライド、メソッド名は変更可能変数をオーバーライドできません" – Nikolaos

答えて

6

ここでは、スーパークラスのセッター/ゲッターを直接参照する必要があります。セッターは問題なくコンパイルされます場合は、ゲッターは、コンパイラは(文字列は暗黙の変換によって、この方法を得ることができます)super.name.apply()として表示されますないので

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. 好意組成物(クラシック):

    は、私はいくつかのオプションを参照してください。

  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 
    } 
    } 
} 

はEDIT:ここではオプション#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 
    } 
    } 
} 
+0

ありがとう - 私はオプション2を避け、何とかあなたのオプション1を使用しようとしていました(オプション3は反射のために質問から外れています)。しかし、オプション1は、プロパティが文字列でなくてもコンパイルされないので、Intで試してみると、私の意味がわかります。あなたが何らかの理由で '名前'フィールドをオーバーライドしようとしているとScalacは思っています...オプション1を取得する方法、 – Nikolaos

+0

オプション1のソリューションを追加しました。 GoFガイドラインに従うと、デコレータデザインパターンでは、既存の実装にビヘイビアを追加できます。 – paradigmatic

関連する問題