假设我有以下特征
trait Foo[T] { def overrideMe(other:Foo[T]) : Int }
我希望能够做到
class Bar extends Foo[Int] { override def overrideMe(other:Bar) : Int = other.BarFn }
但它没有编译.原因是我希望overrideMe能够使用子类型的功能.我可以做点什么
class Bar extends Foo[Int] { override def overrideMe(other:Foo[Int]) : Int = { other.asInstanceOf[Bar].BarFn }
但这看起来不太好.
是否有可能在特征中说可以用子类型覆盖虚函数?
编辑
@agilesteel这几乎可以工作,但如果我在另一个只依赖于特性Foo的类中有一个函数,我会遇到麻烦
class Test[T] { def calloverrideMe(a : Foo[T],b : Foo[T] ) : Int = a.overrideMe(b) }
解决方法
class Test[T] { def calloverrideMe(a : Foo[T],b : Foo[T] ) : Int = a.overrideMe(b) }
当然,你无法使用这个签名.考虑一下
class Baz extends Foo[Int] {...} new Test[Int].calloverrideMe(new Bar,new Baz)
这应该与新的Bar.overrideMe(new Baz)相同,但你不希望它编译!
您可以使用curiously recurring template pattern:
trait Foo[T,Sub <: Foo[T,Sub]] { def overrideMe(other:Sub) : Int } class Bar extends Foo[Int,Bar] { override def overrideMe(other:Bar) : Int = other.BarFn } class Test[T] { def calloverrideMe[Sub <: Foo[T,Sub]](a : Sub,b : Sub) : Int = a.overrideMe(b) }
What I am trying to accomplish is an algorithm relying on a trait and then have some functions implemented in the sub types. Are there any other good design pattern for this?
查看Scalaz类型类.例如. https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Equal.scala