1

2 つのトレイトがあり、そのうちの 1 つは別のトレイトのファクトリであるとします。

trait BaseT {
  val name: String
  def introduceYourself() = println("Hi, I am " +name)
  // some other members ...
}
trait BaseTBuilder {
  def build: BaseT
}

今、私は BaseT を拡張したいと思います:

trait ExtendedT extends BaseT {
  val someNewCoolField: Int
  override def introduceYourself() = {
    super.introduceYourself()
    println(someNewCoolField)
  }
  // some other extra fields

BaseTBuilder新しいフィールドを初期化する方法はわかっているが、スーパークラス メンバーの初期化に使用したいとします。どういうわけかインスタンス化できる特性を作成する可能性はありますExtendedTか? このアプローチは明らかに失敗します。

trait ExtendedTBuilder { self: TBuilder =>
  def build: ExtendedT = {
    val base = self.build()
    val extended = base.asInstanceOf[ExtendedT] // this cannot work
    extended.someNewCoolField = 4  // this cannot work either, assignment to val
    extended
  }
  def buildDifferently: ExtendedT = {
    new ExtendedT(4)  // this fails, we don't know anything about constructors of ExtendedT
  }
  def build3: ExtendedT = {
    self.build() with {someNewCoolField=5} //that would be cool, but it cannot work either
  }
}

誰かが具体的な実装を提供し、次のように書くことでインスタンス化できるような特性(またはオブジェクト)のセットがBaseT欲しいですBaseTBuilderExtendedT

val extendedBuilder = new ConcreteBaseTBuilder with ExtendedTBuilder
val e: ExtendedT = extendedBuilder.build

ExtendedTtype のフィールドを含めることができますがBaseT、必要なすべてのメソッドとフィールドを手動でプロキシする必要があり、これは私の意見では DRY 原則に違反しています。それを解決する方法は?

4

1 に答える 1