如何使父类返回可以匹配子类型的类型?



如何在父类中定义返回类型,使其与子实例类匹配?

在下面的例子中,需要定义echo函数,使其返回调用this的子类的对象。

trait A[T] {
def echo(a: T): T
}
class B extends A[B] {
override def echo(x: B):B = x
}
class C extends B {
def repeat(x: B): B = echo(x)
}
val b = new B()
val c = new C()
// Fails with error value repeat is not a member of B
c.repeat(b).repeat(b) 
// Compilation error
// Found:    B
// Required: D
class D extends B {
def repeat(x: B): D = echo(x)
}
}

你到底想干什么?

如果您跟踪调用链,您将看到c.repeat(b)返回b:B的实例,该实例显然没有repeat方法,该方法在C中定义。

换句话说,在代码中,b.echo(x:B)返回x,而不是this!

也许你想从C.repeat返回this?这应该可以工作:

class C extends B {
def repeat(x: B): C = {
echo(x)
this
}
}
val b = new B()
val c = new C()
c.repeat(b).repeat(b)

正如@Aivean所提到的,您的方法repeat是在类C上定义的,并返回其父类B的实例,该实例没有repeat方法。

所以你不能像do那样调用repeat两次:
val tmpB = c.repeat(b) // tmpB is an instance of B
tmpB.repeat(b)         // fail cuz B has no "repeat" method


现在回答主要问题:"如何使父类返回一个可以匹配子类型的类型?">

与trait A相同,但对其参数类型增加了约束,因此T必须是A:

trait A[T<:A[T]]
class B extends A[B]

阅读更多关于"f界多态"在这个伟大的答案:https://stackoverflow.com/a/21699765/1206998

相关内容

  • 没有找到相关文章

最新更新