2012-04-12 106 views
2

我正在編寫一個程序來模擬人工神經網絡。我有以下的類和接口設置:無法將ArrayList <subtype>轉換爲ArrayList <type>

public interface Neuron 
{ 
} 

// Input neuron 
public class INeuron implements Neuron 
{ 
} 

// Output and hidden neuron 
public class ONeuron implements Neuron 
{ 
} 

public interface Layer 
{ 
    public ArrayList<Neuron> getNeurons(); 
} 

// Input layer 
public class ILayer implements Layer 
{ 
    ArrayList<INeuron> neurons = new ArrayList<INeuron>(); 

    public ArrayList<Neuron> getNeurons() 
    { 
     return neurons; 
    } 

    // other stuff appropriate to the input layer 
} 

編譯器報告「無法從ArrayList中<INeuron>轉換爲ArrayList的<神經>。」

我試過切換東西。例如:ArrayList<Neuron> neurons = new ArrayList<INeuron>()。但這似乎將同樣的錯誤轉移到了班級的不同部分。

我不明白爲什麼INeuron不能隱式投射到神經元,因爲INeuron是Neuron的一個亞型。

+0

正確的解決方案將取決於您對返回列表的用途(只讀?修改?)。出於很好的理由,「通用」不是「通用」。 – trutheality 2012-04-13 01:35:06

回答

8

您需要使用:的

public interface Layer 
{ 
    public ArrayList<? extends Neuron> getNeurons(); 
} 

因爲缺乏仿製藥協變和逆變的。如果返回一個ArrayList < INeuron>作爲一個ArrayList <神經>,那麼你將可能能夠補充一點,是不是INeuron(如神經元的另一個孩子)到一個ArrayList的元素< INeuron>

2

這是一個例子可能發生的一件壞事。

void mymethod (ILayer l) 
{ 
    List<Neuron> neurons = l . getNeurons () ; 
    neurons . add (new ONeuron ()) ; // bad thing 
} 

我的方法mymethod只是污染是ILayerneurons名單與非INeuron。我們推薦Luciano's solution

+0

好搭檔!這是一堂課(我是老師)。我們將在下週更改API以使用Iterator。 – 2012-04-13 00:08:49

+0

@BarryBrown您還必須爲Iterator處理同樣的問題。 – trutheality 2012-04-13 01:37:34

+0

是的,我看到...有更好的解決方案嗎? – 2012-04-13 19:25:56

3

簡單的改變:

ArrayList<INeuron> neurons = new ArrayList<INeuron>(); 

到:

ArrayList<Neuron> neurons = new ArrayList<Neuron>(); 

要能夠滿足兩種類型。

0
public Layer <?> getNeurons(); 

這是另一種編寫子類型的方法,對嗎?

相關問題