2016-09-03 4 views
2

に私はこのようScalaでのvalを上書きしようとしている:オーバーライドヴァルスは、Scalaの

trait T{ 
    val str: String 
} 

sealed abstract class Test extends T{ 
    val str: String = "str" 
} 

class Test1 extends Test{ 
    val str = super.str + "test1" //super may not be used on value str 
} 

しかし、これはコンパイルすることを拒否しました。どうして?抽象クラスの値自体を使用して抽象クラスの値をオーバーライドしたかったのです。これを行う方法?

私の特定のケースでは、I にはクラスパラメータとして渡すことができません。

答えて

4

Scalaコンパイラはvalでスーパーを使用できません。あなたが再評価を心配していない場合は、代わりにdefを使用することができます。

trait T{ 
    def str: String 
} 

sealed abstract class Test extends T{ 
    def str: String = "str" 
} 

class Test1 extends Test{ 
    def str = super.str + "test1" //super may not be used on value str 
} 

defined trait T 
defined class Test 
defined class Test1 
+1

私はこれに同意しますが、あなたはOPコードを変更しませんでした。 :) 'T'は' def str'を持ち、 'Test'は' def str'を持ち、 'Test1'は' def def str'を持っています。 – Alec

+0

haha​​ right :)今、私は、ありがとう! –

3

あなたはそれが繰り返される初期化を避けることについてケアを行う場合は、メソッドにそれを抽出することができます。

sealed abstract class Test extends T { 
    lazy val str: String = initStr 

    protected def initStr = "str" 
} 

class Test1 extends Test{ 
    override protected def initStr = super.initStr + "test1" 
} 

あなたはまた、strlazyを作ることができ、それが終了するのは簡単にすべてですそのような初期化順序の問題でアップ。