我正在尝试使用现有的特征层次结构(我无法控制)并在顶层注入一个方法(然后在层次结构中需要自定义处理的每个点覆盖该方法)。隐含地使用这些特征。下面是一个精简的示例,显示了特征层次结构设置和隐式用法;然后我(失败)尝试注入方法。
使用未实现的方法定义父特征,具有指定类型的子特征和方法的实现形式。创建一个隐含的儿童特质。
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))
}
}
调用方法,指定将隐式拾取Child Trait的类型(Double)。 (这很好用。)
new Utilizer1().utilize[Double](1.0)
这里有些东西不起作用:在父Trait上“注入”一个新方法,并在Child Trait中覆盖它。 (显然,这不是正确的方法 - 如何完成这一部分?)
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
}
}
定义一个类和函数以隐式使用Parent Trait并调用SECOND方法。
class Utilizer2() {
def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
println(trt.doSomething2(x))
}
}
调用方法,指定类型(Double)。它不会隐式地拾取Child Trait而是抛出NotImplementedError。所以它确实找到了doSomething2方法(没有编译错误)但它不尊重层次结构并使用顶层的未实现形式。
new Utilizer2().utilize[Double](1.0)
答案 0 :(得分:0)
您正在执行聚合而不是继承。
BetterParentTrait[T](trt: ParentTrait[T])
这意味着utilize
方法不会看到您的隐式类,因为它具有不同的父/接口。
它必须实现ParentTrait
类才能隐式传递给上述方法。
implicit class BetterParentTrait[T] extends ParentTrait[T]{
def doSomething(x: T): T = ???
def doSomething2(x: T): T = ???
}
答案 1 :(得分:0)
这有帮助吗?
object MainUtilizers {
trait ParentTrait[T] {
def doSomething1(x: T): T
}
trait ChildTrait extends ParentTrait[Double] {
override def doSomething1(x: Double): Double = {
return x + 1.0
}
}
trait BetterParentTrait[T] {
def doSomething2(x: T): T = ???
}
trait BetterChildTrait extends BetterParentTrait[Double] {
override def doSomething2(x: Double): Double = {
return x + 2.0
}
}
//implicit object ChildTrait extends ChildTrait // Commented to avoid 2 implicits for ParentTrait[Double]
implicit object BetterChildTrait extends BetterChildTrait with ChildTrait
class Utilizer1() {
def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
println(trt.doSomething1(x))
}
}
class Utilizer2() {
def utilize[T](x: T)(implicit trt: BetterParentTrait[T]): Unit = {
println(trt.doSomething2(x))
}
}
def main(args: Array[String]) {
new Utilizer1().utilize[Double](1.0)
new Utilizer2().utilize[Double](1.0)
}
}