2013-10-21 115 views
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 
    } 
} 

我想有這樣一組特性(或對象),當有人提供具體落實BaseTBaseTBuilder我可以寫instantiantiate ExtendedT的:

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

ExtendedT可能包含BaseT類型的字段,但這時需要手動代理所有必要的方法和字段,這在我看來是違反DRY原則的。如何解決這個問題?

回答

0

如何在你的ExtendBaseTBuilder

trait ExtendBaseTBuilder { self : BaseTBuilder => 
    def build: ExtendBaseT = { 
    new ExtendBaseT { 
     val someNewCoolField: Int = 3 
    } 
    } 

} 
+0

這樣我們丟棄的'BaseTBuilder'完全完成的工作,這是不好的('BaseT'可以有一些抽象成員創建ExtendBaseT實例,即'BaseTBuilder'填充在)。此外,有人可能會說'TurboBuilder類使用AnotherBuilder擴展BaseTBuilder {def build:使用AnotherT = ...的BaseT'},以便'TurboBuilder'產生類型爲'BaseT with AnotherT'的對象。然後,我們希望'(具有ExtendedTBuilder的新TurboBuilder).build'具有'AnotherT'的ExtendedT類型,這不會發生。 –