函数签名中的Scala继承
我有 然而scala在B的函数签名中的Scala继承,scala,inheritance,scala-2.10,Scala,Inheritance,Scala 2.10,我有 然而scala在B的run功能中抱怨 我对方法签名如何工作感到困惑。类B应该有签名X的方法,但类型Y是类型X 谢谢方法的参数类型是相反的。让我以你为例,解释一下: trait X { } class Y extends X Trait A{ def run(x:X){ /////// } } Class B extends A{ def run(y:Y) } 让我用文字表述一下:为了支持A中定义的接口,B需要能够在其运行方法中使用任何X。因此,您无法确定它将得到的X也是Y 请注意
run
功能中抱怨
我对方法签名如何工作感到困惑。类B应该有签名X的方法,但类型Y是类型X
谢谢方法的参数类型是相反的。让我以你为例,解释一下:
trait X {
}
class Y extends X
Trait A{ def run(x:X){ /////// } }
Class B extends A{ def run(y:Y) }
让我用文字表述一下:为了支持A
中定义的接口,B
需要能够在其运行方法中使用任何X
。因此,您无法确定它将得到的X
也是Y
请注意,实际上允许您执行相反的操作:
val b: B = new B
val y: Y = new Y
b.run(y) // everything is ok
val a: A = b // B is A
val x: X = new X {}
a.run(x) // run on A takes an X. x is of type X
// But: B only takes a Y (more specific type) --> Boom
由于B
在其run方法中接受任何值,因此它也接受X
,因此一切正常
有趣的是,返回值与此相反:
class B extends A { def run(x: Any) = /* snip */ }
这是有效的,因为B
只需返回一些X
。任何Y
也是X
,所以我们很好
我希望这能让您更清楚地了解这里发生了什么,以及为什么编译器禁止您以这种方式实现方法。按照您的解释,如果B实现了run(Any),那么B仍然需要实现run(X),因为类a中的run(X)是抽象的。我也尝试了相反的方法,在A中定义一个抽象运行(any),但是如果B
实现了run(any)
它已经实现了run(X)
,那么B将需要运行(any),因为每个X
也是any
。因此,方法run(Any)
也能够处理它
trait A {
def foo: X
}
class B extends A {
def foo: Y = /* snip */
}