Overriding vals in Scala

2020-02-13 03:20发布

问题:

I have tried to override val in Scala as this:

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
}

But this refused to compile. Why? I wanted to override value in the abstract class using the abstract class's value itself. How to do this?

In my particular case I cannot pass it as a class parameter.

回答1:

Scala compiler does not allow to use super on a val. If you are not caring about re-evaluation, you can just use def instead.

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


回答2:

If you do care about it avoiding repeated initialization, you can extract it into a method:

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

You can also make str non-lazy, but it's all to easy to end up with initialization order problems that way.