Zar*_*s13 1 generics inheritance scala scala-2.10
我有一个奇怪的问题,也许是因为我的课程结构有点复杂,但无论如何:
首先,我有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()
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个扩展TestAbstract2的对象TestObject2,以及扩展TestAbstract1的基本类Test2,并且必须实现valTest:
class Test2 extends TestAbstract1 {
val valTest: TestAbstract2[Test2] = TestObject2
}
object TestObject2 extends TestAbstract2[Test2] { }
Run Code Online (Sandbox Code Playgroud)
问题在于:当我编译时,它告诉我:
[error]覆盖类型为models.test.TestAbstract2 [models.test.TestAbstract1]的类TestAbstract1中的值valTest;
[error] value valTest具有不兼容的类型
[error] val valTest:TestAbstract2 [Test2] = TestObject2
我不知道我做错了什么,因为如果我考虑多态性规则,它应该没问题......
你有什么主意吗 ?或者甚至可能更好地做我想做的事情?
谢谢 !
在您的示例中,TestAbstract2不是协变的.意思是即使我们有
Test2 <: TestAbstract1
Run Code Online (Sandbox Code Playgroud)
事实并非如此:
TestAbstract2[Test2] <: TestAbstract2[TestAbstract1]
Run Code Online (Sandbox Code Playgroud)
如果这对你没有意义,请看看这里.
在您的示例中,valTest声明Test2为类型TestAbstract2[Test2]但预期是TestAbstract2[TestAbstract1],因此错误.
您有以下选择:
声明TestAbstract2为协变:
class TestAbstract2[+T <: TestAbstract1]
Run Code Online (Sandbox Code Playgroud)valTest使用wildchard类型声明:
val valTest: TestAbstract2[_ <: TestAbstract1]
Run Code Online (Sandbox Code Playgroud)参数化TestAbstract1内部的类型TestAbstract2:
class TestAbstract1[T <: TestAbstract1[T]] {
val valTest: TestAbstract2[T]
// ...
}
Run Code Online (Sandbox Code Playgroud)
更改Test2到:
class Test2 extends TestAbstract1[Test2]
Run Code Online (Sandbox Code Playgroud)注意,在第三个例子中使用F-有界多态(在其T自身的函数中的边界TestAbstract1)的选择在某种程度上是任意的.我只是为了示例而需要一些类型,并且在您的示例中它可以工作(当查看定义时Test2).这三个版本中哪一个最适合您取决于您希望如何使用这些类.
如果这还不够,请在您的问题中提供更多详细信息,我们将很乐意为您提供帮助.
| 归档时间: |
|
| 查看次数: |
2540 次 |
| 最近记录: |