1
繼承比方說,我有兩個特點,其中之一是一個工廠的另一個:斯卡拉:與工廠
trait BaseT {
val name: String
def introduceYourself() = println("Hi, I am " +name)
// some other members ...
}
trait BaseTBuilder {
def build: 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
我可以寫instantiantiate ExtendedT
的:
val extendedBuilder = new ConcreteBaseTBuilder with ExtendedTBuilder
val e: ExtendedT = extendedBuilder.build
ExtendedT
可能包含BaseT
類型的字段,但這時需要手動代理所有必要的方法和字段,這在我看來是違反DRY原則的。如何解決這個問題?
這樣我們丟棄的'BaseTBuilder'完全完成的工作,這是不好的('BaseT'可以有一些抽象成員創建ExtendBaseT實例,即'BaseTBuilder'填充在)。此外,有人可能會說'TurboBuilder類使用AnotherBuilder擴展BaseTBuilder {def build:使用AnotherT = ...的BaseT'},以便'TurboBuilder'產生類型爲'BaseT with AnotherT'的對象。然後,我們希望'(具有ExtendedTBuilder的新TurboBuilder).build'具有'AnotherT'的ExtendedT類型,這不會發生。 –