2013-05-19 23 views
0

被添加到列表父我試圖做這樣的事情該編譯罰款:如何亞型可以通過Java泛型

public interface Training { 
    public void train(); 
} 

public class JavaTraining implements Training{ 

    @Override 
    public void train() { 
     // TODO Auto-generated method stub 

    } 


} 

import java.util.*; 

public class TestClass { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     List<Training> trainingList = new ArrayList<Training>(); 
     trainingList.add(new JavaTraining()); 
     for(Training trainingItem : trainingList){ 
      trainingItem.train(); 
     } 

    } 

} 

編譯沒有問題,運行也。

但是,當我嘗試改變像下面的主要方法,它給編譯時錯誤。

這是爲什麼?

import java.util.*; 

public class TestClass { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     List<Training> trainingList = new ArrayList<JavaTraining>(); 
    } 

} 

編譯時錯誤是:

「類型不匹配:不能從ArrayList中轉換到列表」

我甚至看過一個帖子here。但是這並不能證明我的疑問。

的問題是不是this重複的,因爲我沒有在任何地方使用

List<? extends Training> 

但它畢竟是接受JavaTraining的對象。怎麼樣?

回答

4

這就是爲什麼你不能做到這一點:

List<JavaTraining> jt = new ArrayList<JavaTraining>(); // So far so good 
List<Training> trainingList = jt; // This is what you did; let's pretend it compiles 
trainingList.add(new CobolTraining()); // The compiler must allow this, because `CobolTraining` is a `Training`. 

的問題與上面的是,它可以讓你把一個CobolTrainingjt,中JavaTraining列表。

+1

根據Java泛型繼承在嘗試將子類型的對象放入超類型集合時不起作用。 – Sam

+1

@Sam這就是爲什麼中間的這條線被禁止的原因:如果它被允許,你可以通過做你做的事情輕易地繞過限制。 – dasblinkenlight

0

這是由於如何設計泛型。 ArrayList<JavaTraining>不延伸ArrayList<Training>

你應該做

List<? extends Training> trainingList = new ArrayList<JavaTraining>(); 

檢查使用通配符

+0

爲什麼我應該這樣做,如果它沒有它的工作? – Sam