5

以下の例のように、サブクラスで型をリストとして返すメソッドをオーバーライドしようとしていますが、ジェネリックの問題により、サブクラスでそれを行うことができません。スーパー クラス コードを変更できないので、どうすれば問題を解決できますか? 誰でも私を案内してください...事前に感謝します。

更新できないスーパークラス:

public class Animal {
           private String legs;
    }

public class TestSuper {

    public List<Animal> addAnimals() {
        return animals;
    }
}

サブクラス:

public class Dog extends Animal {
         private String sound;
    }

public class TestSub extends TestSuper {

    public List<Dog> addAnimals() { --> I need to override this method but want return type as List of dogs
        return null;
    }
}
4

5 に答える 5

12

スーパー クラスが本当に更新できない場合は、残念ながら更新できません。

スーパークラスを更新できた場合:

では、の代わりにTestSuper使用します。public List<? extends Animal> addAnimals()public List<Animal> addAnimals()

他にどのような解決策がありますか:

このようなユーティリティ メソッドを使用できます。

@SuppressWarnings("unchecked")
public static <T extends Animal> List<T> cast(List<Animal> animals, Class<T> subclass) {
    List<T> out = new ArrayList<T>();
    for (Animal animal : animals) {
        if (!subclass.isAssignableFrom(animal.getClass())) {
            // the "animal" entry isn't an instance of "subclass"
            // manage this case however you want ;)
        } else {
            out.add((T) animal);
        }
    }
    return out;
}

次に、次のように呼び出します。

List<Dog> dogs = TheClassNameYouChose.cast(animals, Dog.class);
于 2013-10-09T15:08:25.433 に答える
0

これを実際に正しく機能させるには、TestSuper にジェネリックを使用させる必要があります。

TestSuper<T extends Animal> {

  public List<T> addAnimals() {

  }
}

TestSub extends TestSuper<Dog> {


}
于 2013-10-09T15:10:28.927 に答える
0

これは不可能です。スーパークラスの契約では、次の場合:

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

次のコードは有効である必要があります。

TestSuper test = new AnySubclassOfTestSuper(); // including TestSub!
test.addAnimals().add(new Cat());

aに a をTestSub追加できないため、クラスでのオーバーライドはそれに違反します。これはオブジェクト指向型システムのかなり基本的な原則に違反するため、この制限に対する完全な回避策を見つけることはできません。CatList<Dog>

List<? extends Animal>そのリストには何も追加できないため、使用するスーパークラスを変更するという提案は機能します。

于 2013-10-09T15:35:17.910 に答える