[英]scala - implementing trait method with parameter that is child of expected type
我是Scala的新手,所以如果这是一个简单的问题,请原谅我,但是我找不到任何可以帮助我的东西,或者我找不到正确的搜索词。 我该如何进行这项工作?
scala> trait Foo
defined trait Foo
scala> class FooImpl extends Foo
defined class FooImpl
scala> trait Bar { def someMethod(foo: Foo) }
defined trait Bar
scala> class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }
<console>:10: error: class BarImpl needs to be abstract, since method someMethod in trait Bar of type (foo: Foo)Unit is not defined
(Note that Foo does not match FooImpl)
class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }
由于Foo是特质,为什么FooImpl不匹配Foo? 我猜想我需要在Bar中更改someMethod的签名,以表示我期望扩展Foo或“ with Foo”的东西,但是我似乎找不到有关此文件的文档。
问题在于Bar
特性的someMethod
声明指定可以将任何类型的Foo
作为参数传递。 您可以将其视为其“合同”。 合同说的任何实现Bar
将有一个方法someMethod
将接受任何形式的Foo
。
您的BarImpl
类是Bar
的实现,并且具有someMethod
实现。 不幸的是,它对someMethod
实现只接受FooImpl
类型的Foo
对象:不接受任何类型的Foo
。 由于它不允许您传入不是FooImpl
对象的Foo
对象,因此它违反了特征定义所指定的约定。 实施的限制不得超出合同规定的范围。
举个例子:
class FooImplB extends Foo
val bar: Bar = new BarImpl
val foo: Foo = new FooImplB
bar.someMethod(foo)
在这里,我们声明一个称为bar
的Bar
和一个称为foo
的Foo
。 根据Foo
的定义,我应该能够将foo
传递给bar.someMethod
。 除了BarImpl.someMethod
仅接受FooImpl
类型的Foo
而不接受FooImpl
FooImplB
! 所以我们有一个问题。
dhg解释了为什么这行不通以及为什么您可能真的不想要它。
但是,如果您仍然想要它,您可以这样做:
trait Foo
class FooImpl extends Foo
trait Bar[F <: Foo] { def someMethod(foo: F) }
class BarImpl extends Bar[FooImpl] {
def someMethod(foo: FooImpl) {}
}
Jens Schauder的答案有效,但会迫使您在特征签名中定义类型。 相反,您可以在方法级别执行相同的操作:
scala> trait Foo
defined trait Foo
scala> class FooImple extends Foo
defined class FooImple
scala> trait Bar { def methodA[T <: Foo](foo: T) }
defined trait Bar
scala> class BarImpl extends Bar { def methodA[FooImpl](foo: FooImpl){} }
defined class BarImpl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.