2

Java では、非共変の戻り値の型がコンパイル時エラーを生成するときに、共変の戻り値の型が受け入れられるのはなぜですか。確かに、JVM が共変の戻り値の型を処理できる場合は、非共変の戻り値の型を処理できます。Java が共変の戻り値を持つオーバーライドされたメソッドを見ると、呼び出し元のオブジェクトに関連付けられているメソッドを適用するだけだと思います。非共変の戻り値の型で同じことが起こらないのはなぜですか。私の推測では、それはスーパークラスのメソッド コントラクトの条件を破ることに関係していると考えられます。もちろん、これが許可された場合、サブクラスの (オーバーライドされた) メソッドの動作はあまり予測できません (戻り値の型に一貫性がないため)。 ?

以下に例を示します (DogFood は Food のサブクラスですが、CatFood は Food のサブクラスではないと仮定します)。

動物クラス

public class Animal {

public Food seekFood() {

    return new Food();
}
}

ドッグクラス

public class Dog extends Animal {

public DogFood seekFood() { //This is OK since its a covariant

    return new DogFood();
}
}

猫クラス

    public class Cat extends Animal {

public CatFood seekFood() { // This won't compile. Catfood is not covariant

    return new CatFood();
}
}
4

2 に答える 2

0

2 つのメソッドが同じシグネチャ (メソッド名と引数の型) を持っている場合、コンパイラはどちらのメソッドを呼び出すかを決定できません。2 つのメソッドの名前が同じで、引数の型と戻り値の型が異なる場合、それらのシグネチャは異なり、コンパイラはどちらを呼び出すかを選択できます。

更新: javac は共変メソッドをその基本クラス メソッドにコンパイルし、それを呼び出すと、基本クラス メソッドはサブクラス メソッドへの呼び出しを委譲します。それらは異なる型を返すため、型キャストはできません。A. Sundararajan の Weblog のおかげで、そのプロセスは 1 つのコード スニペットで非常に明確に説明できます。

class CircleFactory extends ShapeFactory {
    public Circle newShape() {
       // your code from the source file
       return new Circle();
    }

    // javac generated method in the .class file
    public Shape newShape() {
       // call the other newShape method here -- invokevirtual newShape:()LCircle;
    } 
}
于 2016-03-08T18:51:56.127 に答える
0
class A {
    Ra f(Pa x) { ... }
}

class B extends A {
    @Override
    Rb f(Pb x) { ... }
}

継承規則は、共変/反変の動作を決定します。

T 型の値は、T 型または親型の変数にのみ割り当てることができます。

メソッド呼び出しは、実際のメソッド引数 (1) をローカル パラメーター (2) に割り当て、結果値 (1) を使用する場所 (2) に割り当てることを意味します。

コンパイラが実際に B になる可能性のある A オブジェクトに遭遇した場合B.f、有効なオーバーライドになります。

  1. Pb は、Pa または親クラス (反変) の場合にのみ有効です。

    B.f少なくとも Pa 値を受け取ることができなければならないからです。

  2. Rb は、Ra または子クラス (共変) の場合にのみ有効です。

    B.fRa に割り当て可能なものを返す必要があるためです。

これにより、子クラスはより限定的で具体的になります。

目の前のケースでは、Cat は、DogFood が Food の子である場合、DogFood を返す場合があります。したがって、動物が実際に猫であっても、動物の食べ物は実際に食べ物です。

于 2016-03-08T20:27:48.267 に答える