我有一个奇怪的问题,也许是因为我的课程结构有点复杂,但无论如何:
首先,我有2个抽象类:TestAbstract1和TestAbstract2。
代码:
abstract class TestAbstract1 {
val valTest: TestAbstract2[TestAbstract1]
def meth1(): List[TestAbstract1] = {
valTest.meth2()
}
}
abstract class TestAbstract2[T <: TestAbstract1] {
def meth2(): List[T] = {
List()
}
}
然后我有一个扩展TestAbstract2的对象 TestObject2 ,以及扩展TestAbstract1的基本类 Test2 ,并且必须实现 valTest :< / p>
class Test2 extends TestAbstract1 {
val valTest: TestAbstract2[Test2] = TestObject2
}
object TestObject2 extends TestAbstract2[Test2] { }
问题在于:当我编译时,它告诉我:
[error]覆盖类型为models.test.TestAbstract2 [models.test.TestAbstract1]的类TestAbstract1中的值valTest;
[error] value valTest具有不兼容的类型
[error] val valTest:TestAbstract2 [Test2] = TestObject2
我不知道我做错了什么,因为如果我考虑多态性规则,它应该没问题......
你知道吗?或者甚至可能更好地做我想做的事情?谢谢!
答案 0 :(得分:5)
在您的示例中,TestAbstract2
不是协变的。意思是即使我们有
Test2 <: TestAbstract1
情况并非如此:
TestAbstract2[Test2] <: TestAbstract2[TestAbstract1]
如果这对您没有意义,请查看here。
在您的示例中,valTest
中声明的Test2
类型为TestAbstract2[Test2]
,但预计为TestAbstract2[TestAbstract1]
,因此错误。
您有以下选择:
将TestAbstract2
声明为协变:
class TestAbstract2[+T <: TestAbstract1]
使用wildchard类型声明valTest
:
val valTest: TestAbstract2[_ <: TestAbstract1]
对内部TestAbstract1
的类型进行参数化TestAbstract2
:
class TestAbstract1[T <: TestAbstract1[T]] {
val valTest: TestAbstract2[T]
// ...
}
将Test2
更改为:
class Test2 extends TestAbstract1[Test2]
请注意,在第三个示例中使用F-bounded多态(在T
中使用自身函数绑定TestAbstract1
)的选择在某种程度上是任意的。我只是为了示例而需要一些类型,并且在您的示例中它可以工作(当查看Test2
的定义时)。这三个版本中哪一个最适合您取决于您希望如何使用这些类。
如果这还不够,请在问题中提供更多细节,我们很乐意为您提供帮助。