2013-10-09 16 views
2

覆蓋泛型列表返回類型試圖超越其子類返回類型列表類似如下例所示,由於仿製藥的問題,我不能做到這在我的子類中的方法。我無法更改我的超類代碼,所以我可以如何解決問題?任何人都可以請指導我...很多提前感謝。我如何在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; 
    } 
} 
+0

您只能用賦值兼容類型覆蓋返回類型。但是,泛型不是協變的。 '列表'不是'列表'的子類型。請參閱[此線程](http://stackoverflow.com/questions/14694852/can-overridden-methods-differ-in-return-type)。 –

回答

7

如果超類真的不能被更新,恐怕你根本不能。

如果你已經能夠更新超類:

TestSuper,你就必須使用public List<? extends Animal> addAnimals()代替public List<Animal> addAnimals()

什麼其他的解決辦法(S)你有:

你可以使用這樣的工具方法:

@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); 
+0

感謝您的回覆,但我點在我的項目中有這個選項,由於這個原因期待的建議:( – Satya

+0

@Satya看到我的更新,也許這可能有所幫助。 – sp00m

+0

想要使用addAnimals() class ...因此我想重寫 – Satya

0

您需要使TestSuper使用泛型來真正地使這個工作正確。

TestSuper<T extends Animal> { 

    public List<T> addAnimals() { 

    } 
} 

TestSub extends TestSuper<Dog> { 


} 
1

如果DogAnimal一個子類,你可能做

以下特徵:

public List<? extends Animal> addAnimals() 

然後在子類做

public List<Dog> addAnimals() 

或者你可以讓超類的通用<T>和實現類<Dog>

2

你不能泛型類型列表更改爲通用型的亞型。問題在於對任何實例的引用都可以是該實例的子類型。所以讓我們看看這個例子

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

所以,你會添加Cat列出應該只包含Dogs,這是不對的。


此外,在重寫的方法,你不能改變泛型類型列表與一般類型的超類型列出(如List<Dog>List<Animal>)。爲什麼?讓我們來看看這個例子

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

在亞型,我們有動物的列表,從而有可能get(0)將返回貓。


如果你能在你的類更改代碼,然後嘗試,也許這種方法

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

class Sub extends Super<Dog> { 

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

這是不可能的。超一流的合同說,如果您有:

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

下面的代碼必須是有效的:

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

你在TestSub類重寫就會違背,因爲你不能添加CatList<Dog>。由於它違反了面向對象類型系統的一個相當基本的原則,所以你不會爲這個限制找到一個完美的解決方法。

將超類更改爲使用List<? extends Animal>的建議可行,因爲您無法向該列表中添加任何內容。