1. ホーム
  2. java

[解決済み] Javaでオーバーロードとオーバーライドの両方で共分散と共分散を示す関数の例を挙げてください。[クローズド]

2022-10-19 18:15:46

質問

Javaで共分散と共分散の良い例を示してください。

どのように解決するのですか?

共分散です。

class Super {
  Object getSomething(){}
}
class Sub extends Super {
  String getSomething() {}
}

Sub#getSomethingはSuper#getSomethingの戻り値のサブクラスを返すので共変量です(ただしSuper.getSomething()の契約を履行する)。

共変

class Super{
  void doSomething(String parameter)
}
class Sub extends Super{
  void doSomething(Object parameter)
}

Sub#doSomethingはSuper#doSomethingのパラメータのスーパークラスのパラメータを取るので、contravariantです(ただし、ここでもSuper#doSomethingの契約を満たしている)。

注意:この例はJavaではうまくいきません。Java コンパイラーは doSomething()-Method をオーバーライドせず、オーバーロードしてしまうからです。他の言語では、このスタイルのContravarianceをサポートしています。

ジェネリックス

Genericsでも可能です。

List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;

のすべてのメソッドにアクセスできるようになりました。 covariantList のすべてのメソッドにアクセスできるようになりました。 しかし、ゲッターは問題なく動作します(返されるオブジェクトは常に "Object" 型であるため)。

その逆は contravariantList : 一般的なパラメータを持つすべてのメソッドにアクセスできますが(それは "String" のスーパークラスでなければならないことが分かっているので、常に1つを渡すことができます)、ゲッターはありません(戻り値の型は String の他のスーパータイプであってもかまいません)。