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
欲しいですBaseTBuilder
:ExtendedT
val extendedBuilder = new ConcreteBaseTBuilder with ExtendedTBuilder
val e: ExtendedT = extendedBuilder.build
ExtendedT
type のフィールドを含めることができますがBaseT
、必要なすべてのメソッドとフィールドを手動でプロキシする必要があり、これは私の意見では DRY 原則に違反しています。それを解決する方法は?