无法将ArrayList 转换为ArrayList

无法将ArrayList <subtype>转换为ArrayList <type>

问题描述:

我正在编写一个程序来模拟人工神经网络。我有以下的类和接口设置:无法将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

您需要使用:的

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

因为缺乏仿制药协变和逆变的。如果返回一个ArrayList < INeuron>作为一个ArrayList <神经>,那么你将可能能够补充一点,是不是INeuron(如神经元的另一个孩子)到一个ArrayList的元素< INeuron>

这是一个例子可能发生的一件坏事。

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

简单的改变:

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

到:

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

要能够满足两种类型。

public Layer <?> getNeurons(); 

这是另一种编写子类型的方法,对吗?