Dart: covariant キーワードの使い方

Dart: covariant キーワードの使い方

August 19, 2024

covariant キーワードについて #

以下のコードは SubClass の method の部分でエラーになります。エラーメッセージは以下です。

'SubClass.method' ('void Function(ArgumentOfSubClass)') isn't a valid override of 'SuperClass.method' ('void Function(ArgumentOfSuperClass)').
class SuperClassArg {}

class SubClassArg extends SuperClassArg {}

class SuperClass {
  void method(SuperClassArg arg) {
    // Do something...
  }
}

class SubClass extends SuperClass {
  @override
  void method(SubClassArg arg) {
    // Do something...
  }
}

以下のようにすることでエラーは解消します。

class SubClass extends SuperClass {
  @override
  void method(SuperClassArg arg) { // 👈 引数の型を SuperClassArg に変えた
    // Do something...
  }
}

ただし、これは望んだ形ではないはずです。サブクラスとしては、あくまでサブクラス用に限定された引数を受け取りたいという思いがあります。こういった場面では covariant のキーワードを付与しましょう。

class SubClass extends SuperClass {
  @override
  void method(covariant SubClassArg arg) { // 👈 covariant キーワードを指定
    // Do something...
  }
}

親クラスで指定することもできる #

covariant キーワードは親クラス、子クラスのどちらでも指定することができます。

先ほどの例のように子クラスで指定した場合、covariant が適用されるのはその子クラスのメソッドのみです。

class SuperClassArg {}

class SubClassArg extends SuperClassArg {}

class SuperClass {
  void method(SuperClassArg arg) {
    // Do something...
  }
}

class SubClassA extends SuperClass {
  @override
  void method(covariant SubClassArg arg) { // 👈 こちらのエラーは解消されるが...
    // Do something...
  }
}

class SubClassB extends SuperClass {
  @override
  void method(SubClassArg arg) { // 👈 こちらのエラーは残ったまま
    // Do something...
  }
}

すべての子クラスに covariant を適用したい場合、親クラスで指定することで継承先のメソッドに一律適用することができます。

class SuperClassArg {}

class SubClassArg extends SuperClassArg {}

class SuperClass {
  void method(covariant SuperClassArg arg) { // 👈 親クラスで指定する
    // Do something...
  }
}

class SubClassA extends SuperClass {
  @override
  void method(SubClassArg arg) {
    // Do something...
  }
}

class SubClassB extends SuperClass {
  @override
  void method(SubClassArg arg) {
    // Do something...
  }
}

参考 #