我試圖採取現有的特徵層次結構(我無法控制)並在頂層注入方法(然後在每個點上覆蓋該方法在需要定製治療的層次結構中)。這些特徵隱含地使用。下面是一個修剪過的示例,顯示特徵層次結構設置和隱含用法;然後我(失敗)嘗試注入方法。使用implicits注入特徵層次結構的多個級別的方法
定義與未實現的方法,一個孩子性狀與指定類型和該方法的一個實施形式的父性狀。創建一個隱含的兒童特質。
trait ParentTrait[T] {
def doSomething1(x: T): T
}
trait ChildTrait extends ParentTrait[Double] {
override def doSomething1(x: Double): Double = {
return x + 1.0
}
}
implicit object ChildTrait extends ChildTrait
定義一個類和函數來隱式使用Parent Trait並調用該方法。
class Utilizer1() {
def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
println(trt.doSomething1(x))
}
}
調用方法,指定類型(Double),它將隱式地拾取Child Trait。 (這工作得很好。)
new Utilizer1().utilize[Double](1.0)
這就是事情不工作:「注入」新的方法到父特質,並在兒童特質覆蓋它。 (顯然,這是不是這樣做的正確方法 - 如何做到這一點的一部分)
implicit class BetterParentTrait[T](trt: ParentTrait[T]) {
def doSomething2(x: T): T = ???
}
implicit class BetterChildTrait(trt: ParentTrait[Double]) extends BetterParentTrait[Double](trt) {
override def doSomething2(x: Double): Double = {
return x + 2.0
}
}
定義一個類和函數隱含使用父特質,並呼籲第二種方法。
class Utilizer2() {
def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
println(trt.doSomething2(x))
}
}
調用方法,指定類型(雙精度型)。它不隱式地拾取子特質,而是拋出一個NotImplementedError。所以它找到了doSomething2方法(沒有編譯錯誤),但它不尊重層次結構,並使用頂層的未實現形式。
new Utilizer2().utilize[Double](1.0)
這適用於我的實際問題,這是非常有用的。如果不需要在Utilizer2中指定BetterParentTrait將會很好 - 我不能動搖那種必須有某種方式來實現這一點的感覺,但我對Scala也很陌生,所以我可能只是錯了! –
很高興知道它有幫助。 明天我會再試一次,看看我能不能做出你想要的。雖然我不確定優勢。 –
對不起,我沒有找到在Utilizer2中使用ParentTrait的方法。當您添加doSomething2時,您將其有效地添加到ChildTrait而不是ParentTrait [T],因此只有默認實現在範圍內。 –