19
scala> class C
defined class C

scala> class subC extends C
defined class subC

scala> class A { type T = C}
defined class A

scala> class subA extends A { override type T = subC}
<console>:10: error: overriding type T in class A, which equals C;
 type T has incompatible type
      class subA extends A { override type T = subC}
                                           ^

上記の例では、クラスの型フィールドをオーバーライドできないというエラー メッセージが表示されますA(選択した型subCがクラスを拡張した場合でもC)。

タイプフィールドをオーバーライドすることはまったく可能ですか? はいの場合、上記の例の何が問題になっていますか?

4

1 に答える 1

27

タイプに関して「オーバーライド」について話すのではなく、その範囲を狭めることについて話します。

  1. type T...限界はありません
  2. type T <: C...TCまたはのサブタイプC(これは上界と呼ばれます)
  3. type T >: C...TCまたはのスーパータイプ(下限Cと呼ばれます)
  4. type T = C...T正確にC(タイプエイリアス)

したがって、Tが特性のタイプメンバーでAありSubA、のサブタイプであるA場合、(2)のSubA場合Tはより特定のサブタイプCに絞り込むことができますが、(3)の場合はより高いスーパータイプのに絞り込むことができCます。ケース(1)は、に制限を課しませんがSubA、ケース(4)は、Tいわば「最終」であることを意味します。


これは、メソッドの引数の型として表示されるか、メソッドの戻り型として表示されるかにかかわらず、 Tinの使いやすさに影響を及ぼします。A

例:

trait C { def foo = () }
trait SubC extends C { def bar = () }

trait MayNarrow1 {
  type T <: C  // allows contravariant positions in MayNarrow1
  def m(t: T): Unit = t.foo  // ...like this
}

object Narrowed1 extends MayNarrow1 {
   type T = SubC
}

object Narrowed2 extends MayNarrow1 {
  type T = SubC
  override def m(t: T): Unit = t.bar
}

タイプは(メソッド引数のタイプとして)反変の位置で発生するmためMayNarrow1、メソッドを定義することができます。したがって、のサブタイプで絞り込まれた場合でも有効です(メソッド本体はタイプであるかのように扱うことができます)。TTMayNarrow1tC

対照的に、type T = C必然的に修正されますT。これは、メソッドの作成に対応しfinalます。を固定することにより、共変位置で(メソッドの戻り型として)T使用できます。

trait Fixed extends MayNarrow1 {
  type T = C   // make that T <: C to see that it won't compile
  final def test: T = new C {}
}

これで、さらに「オーバーライド」することを禁止する必要があることが簡単にわかりますT

trait Impossible extends Fixed {
  override type T = SubC

  test.bar  // oops...
}

完全を期すために、これは下限のあまり一般的ではないケースです。

trait MayNarrow2 {
  type T >: SubC  // allows covariant positions in MayNarrow2
  def test: T = new SubC {}
}

object Narrowed3 extends MayNarrow2 {
  type T = C
  test.foo
}

object Narrowed4 extends MayNarrow2 {
  type T = C
  override def test: T = new C {}
}
于 2012-06-30T14:33:00.650 に答える