开发者

In Scala, can I override a concrete field containing a list and append something to it in the subclass?

Here's a simplification of the classes I have:

trait RequiredThings {
  val requiredThings: Seq[String]
}

class SimpleCalculator with RequiredThings {
  val requiredThings = List("a", "b")
}

class ComplicatedCalculator extends SimpleCalculator with RequiredThings {
  self: SimpleCalculator =>
  override val requiredThings:List[String] = List("c") ::: self.requiredThings
}

In this version, I'm using a self-type annotation, but I'm not completely positive that's the way to go. I think I could probably get it to work by conver开发者_开发问答ting requiredThings to a method throughout, but I'd like to try it as a field.

Final solution:

trait RequiredThings {
  def requiredThings: Seq[String]
}

class SimpleCalculator with RequiredThings {
  def requiredThings = List("a", "b")
}

class ComplicatedCalculator extends SimpleCalculator with RequiredThings {
  override def requiredThings:List[String] = List("c") ::: super.requiredThings
}


Yes, super calls to methods "inherited" through the self-type are not yet implemented. This will change (somewhat) soon. In the meantime, you should use inheritance instead.


Funny enough, I stepped on the same issue yesterday.

The way self types are implemented currently, if you override a method (or value) there's no way to refer to the overridden method.

The following will loop:

class A { def foo = "a" }
trait B { self: A => override def foo = self.foo + "b" }

(note: you cannot call super.foo, the parent of B is ScalaObject, not A)

I also tried with one more indirection, but the program still loops.

class A { def foo = "a"; def fooA = A.this.foo }
trait B { this: A => override def foo = fooA + "b" }

There is work going on currently on self types, maybe this will change.


It makes sense to have requiredThings as a def at least in the trait - this will give you more flexibility

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜