Scala:泛型和变量继承问题

时间:2013-06-29 00:28:46

标签: scala generics inheritance scala-2.10

我有一个奇怪的问题,也许是因为我的课程结构有点复杂,但无论如何:

首先,我有2个抽象类:TestAbstract1和TestAbstract2。

  • TestAbstract2 采用扩展TestAbstract1
  • 的类型
  • TestAbstract1 声明一个名为 valTest 的val,类型为TestAbstract2 [TestAbstract1],必须在子类中实现

代码:

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

我不知道我做错了什么,因为如果我考虑多态性规则,它应该没问题......

你知道吗?或者甚至可能更好地做我想做的事情?

谢谢!

1 个答案:

答案 0 :(得分:5)

在您的示例中,TestAbstract2不是协变的。意思是即使我们有

Test2 <: TestAbstract1

情况并非如此:

TestAbstract2[Test2] <: TestAbstract2[TestAbstract1]

如果这对您没有意义,请查看here

在您的示例中,valTest中声明的Test2类型为TestAbstract2[Test2],但预计为TestAbstract2[TestAbstract1],因此错误。

您有以下选择:

  1. TestAbstract2声明为协变:

    class TestAbstract2[+T <: TestAbstract1]
    
  2. 使用wildchard类型声明valTest

    val valTest: TestAbstract2[_ <: TestAbstract1]
    
  3. 对内部TestAbstract1的类型进行参数化TestAbstract2

    class TestAbstract1[T <: TestAbstract1[T]] {
      val valTest: TestAbstract2[T]
      // ...
    }
    

    Test2更改为:

    class Test2 extends TestAbstract1[Test2]
    
  4. 请注意,在第三个示例中使用F-bounded多态(在T中使用自身函数绑定TestAbstract1)的选择在某种程度上是任意的。我只是为了示例而需要一些类型,并且在您的示例中它可以工作(当查看Test2的定义时)。这三个版本中哪一个最适合您取决于您​​希望如何使用这些类。

    如果这还不够,请在问题中提供更多细节,我们很乐意为您提供帮助。