在Scala中覆盖通用特征的方法

时间:2016-03-15 23:02:31

标签: scala generics

我定义了一个通用的环境特征:

trait Environment[T]

我提供了这个实现:

class MyEnvironment extends Environment[Integer] {
 val specific: Integer = 0
}

此外,我定义了一个通用事件特征,它具有一个接受通用环境作为参数的方法:

trait Event[T] {
  def exec(e: Environment[T])
}

对于此事件特征,我提供了以下实现,其中exec()方法接受MyEnvironment类型的参数,以使我能够访问MyEnvironment的特定值。

class MyEvent extends Event[Integer] {
  override def exec(e: MyEnvironment): Unit = {
    println(e.specific)
  }
}

但是,Scala编译器会从中看出错误  MyEnvironment未被识别为环境[整数]:

  

错误:方法exec不会覆盖任何内容。

     

注意:类MyEvent的超类包含以下非最终成员,名为exec:def exec(t:main.vub.lidibm.test.Environment [Integer]):Unit

是否可以使这项工作成功,或者是否有模式可以解决这个问题。

2 个答案:

答案 0 :(得分:3)

您无法缩小方法的签名范围;它不再是同一种方法了。在您的情况下,您无法覆盖

def exec(e: Environment[T]): Unit

override def exec(e: MyEnvironment): Unit 

第二种方法比第一种方法更具体。它在概念上与例如使用def def foo(a: Any)覆盖foo(s: String)

如果您希望它起作用,您需要在两个签名中使用相同的类型(请注意,如果使用上限,例如T <: Environment[_],则表示实际接受T的方法接受Environment的任何子类,因此在这种情况下使用MyEnvironment覆盖将正常工作。)

答案 1 :(得分:0)

因为覆盖在方法的参数类型中不是多态的。它的工作方式与Java相同。在示例中,您所做的是实际重载该方法。这就是它们被视为不同的方法 用于覆盖方法名称,即。名称,签名,类型必须相同。