假设我具有以下特征

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)
}

我收到一个编译错误:类型不匹配;找到b.type(基础类型为foo.Foo [T])为必需的a.SubType

最佳答案

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)

这应该与new 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)
}



查看Scalaz类型类。例如。 https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Equal.scala

关于scala - 特质中的覆盖功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7153129/

10-12 00:42