簡體   English   中英

如何在java中覆蓋泛型列表返回類型

[英]How to override generic list return type in java

我試圖覆蓋返回類型為子類中的列表的方法,如下例所示,由於泛型問題,我無法在子類中執行此操作。 我無法改變我的超類代碼,所以我如何解決這個問題? 任何人都可以指導我...非常感謝提前。

無法更新的超級課程:

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;
    }
}

如果超級班真的無法更新,我恐怕你根本就不能。

如果您能夠更新超類:

TestSuper ,你會使用public List<? extends Animal> addAnimals() 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);

您不能將List的泛型類型更改為該泛型類型的子類型。 問題是對任何實例的引用都可以是該實例的子類型。 讓我們來看看這個例子

SuperType sup = new SubType();
sup.getAnimals().add(new Cat());
//adding cat is possible because getAnimals() returns List<Animal>

所以你要將Cat添加到應該只包含Dogs列表中,這是錯誤的。


同樣在重寫方法中,您不能將通用類型的列表更改為使用該泛型類型的超類型List<Dog> (例如List<Dog> to List<Animal> )。 為什么? 讓我們來看看這個例子

SuperType sup = new SubType();
Dog d = sup.getAnimals().get(0);

在子類型中我們有動物列表,因此get(0)可能會返回Cat。


如果您可以更改類中的代碼,那么可以試試這種方法

class Super<T extends Animal> {
    public List<T> addAnimals() {
        return null;
    }
}

class Sub extends Super<Dog> {

    @Override
    public List<Dog> addAnimals() {
        return null;
    }
}

如果DogAnimal的子類,你可能會這樣做

以下簽名:

public List<? extends Animal> addAnimals()

然后做

public List<Dog> addAnimals()

在子類中。

或者你可以使超類泛型<T>和實現類<Dog>

您需要使TestSuper使用泛型來真正使其正常工作。

TestSuper<T extends Animal> {

  public List<T> addAnimals() {

  }
}

TestSub extends TestSuper<Dog> {


}

這是不可能的。 超級合同說如果你有:

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

以下代碼必須有效:

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

您在TestSub類中的覆蓋會違反該規則,因為您無法將Cat添加到List<Dog> 由於它違反了面向對象類型系統的相當基本原則,因此您無法找到這種限制的完美解決方法。

建議更改超類使用List<? extends Animal> List<? extends Animal>將起作用,因為您無法向該列表添加任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM