1

クラスの構造が少し複雑なためか、興味深い問題がありますが、とにかく:

まず、TestAbstract1 と TestAbstract2 の 2 つの抽象クラスがあります。

  • TestAbstract2は TestAbstract1を拡張する型を取ります
  • TestAbstract1は、子クラスで実装する必要があるタイプ TestAbstract2[TestAbstract1] の valTestという名前の val を宣言します

コード :

abstract class TestAbstract1 {
    val valTest: TestAbstract2[TestAbstract1]

    def meth1(): List[TestAbstract1] = {
        valTest.meth2()
    }
}

abstract class TestAbstract2[T <: TestAbstract1] {
    def meth2(): List[T] = {
        List()
    }
}

次に、TestAbstract2 を拡張する 1 つのオブジェクトTestObject2と、TestAbstract1 を拡張する基本クラスTest2があり、 valTestを実装する必要があります。

class Test2 extends TestAbstract1 {
    val valTest: TestAbstract2[Test2] = TestObject2
}

object TestObject2 extends TestAbstract2[Test2] { }

問題はここにあります:コンパイルすると、次のように表示されます:

[エラー] タイプ models.test.TestAbstract2[models.test.TestAbstract1] のクラス TestAbstract1 の値 valTest をオーバーライドしています。

[エラー] 値 valTest に互換性のない型があります

[エラー] val valTest: TestAbstract2[Test2] = TestObject2

ポリモーフィズムのルールを考えれば大丈夫なはずなので、何が間違っているのかわかりません...

何か考えはありますか?それとも、私がやりたいことを行うためのより良い方法でしょうか?

ありがとうございました !

4

1 に答える 1

5

あなたの例でTestAbstract2は、共変ではありません。つまり、持っていたとしても

Test2 <: TestAbstract1

次の場合は当てはまりません。

TestAbstract2[Test2] <: TestAbstract2[TestAbstract1]

これが意味をなさない場合は、こちらをご覧ください。

あなたの例ではvalTest、宣言されてTest2いるのは型ですTestAbstract2[Test2]が、であると予想されるTestAbstract2[TestAbstract1]ため、エラーです。

次のオプションがあります。

  1. TestAbstract2共変として宣言します。

    class TestAbstract2[+T <: TestAbstract1]
    
  2. valTestワイルドチャード タイプを使用して宣言します。

    val valTest: TestAbstract2[_ <: TestAbstract1]
    
  3. TestAbstract1inner の型をパラメータ化しTestAbstract2ます:

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

    変更Test2:

    class Test2 extends TestAbstract1[Test2]
    

3 番目の例でF-bounded polymorphism (T関数自体による境界) を使用するという選択はTestAbstract1、ここでは多少恣意的であることに注意してください。例のためにいくつかの型を入れる必要がありましたが、あなたの例ではそれが機能します(の定義を見るとTest2)。これら 3 つのバージョンのどれが最適かは、これらのクラスをどのように使用するかによって異なります。

これで十分でない場合は、質問に詳細を記入してください。喜んでお手伝いさせていただきます。

于 2013-06-29T00:50:46.433 に答える