繁体   English   中英

scala-使用参数为预期类型的​​子代来实现特征方法

[英]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)

在这里,我们声明一个称为barBar和一个称为fooFoo 根据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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM