我能否在Scala中使用具体类型覆盖带有类型参数的方法?

4
我想通过将具体类型分配给类型参数来覆盖类型参数化方法,就像下面的代码一样。
trait A {
  def amethod[T](x: T): T
}
trait B extends A {
  def amethod(x: String): String = x ++ x
}

然而编译器会报错:"amethod overrides nothing"。在Trait B中,我不能在amethod后面加上"[String]",因为从语法上讲,它被认为是一个类型参数名为String,而不是java.lang.String类型。我想知道是否有一种方法可以实现这样的效果。
非常感谢。

2
你是否能控制特质 A?如果可以,你可以将其作为类型参数 T,并使 B 成为 A [String] 的子类型。 - jub0bs
2
No. B 违反了与 A 的合同。 - Michael Zajac
这对我完美地运作了。您能解释一下问题在哪里吗? trait A { def amethod[T](x: T): T }; trait B extends A { def amethod[String](x: String) = x }; class C extends B {}; val c= new C(); c.amethod("Hello"); res5: String = Hello - rogue-one
@rogue-one 试着调用 c.amethod(1) - Alexey Romanov
2个回答

5
amethod是在traitA中定义的通用方法,这意味着每次调用都可以应用于通用参数。
您在traitB中试图表达的是更改通用性表达的范围,将其从调用站点移动到类定义本身。这是不可能的。
正如评论中建议的那样,如果要在类定义中表达通用性,则应将类型参数应用于类,而非方法:
 trait A[T] {
   def amethod(x: T): T
 }

 trait B extends A[String] {
   override def amethod(x: String): String = x ++ x
 }

2
作为对评论“B违反了与A的合约”的解释,请考虑以下代码:
def foo(): A = new B {} // legal because B extends A
def bar = foo().amethod[Int](0)

应该发生什么事情?如果你倾向于认为它应该被拒绝,通过查看foo的主体,请想象它是一个抽象方法,而某个类恰好以这种方式实现了它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接