我正在编写一个模拟人工神经网络的程序。我设置了以下类和接口:
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&lt; INeuron&gt;转换为ArrayList&lt; Neuron&gt ;.”
我试过切换东西。例如:ArrayList<Neuron> neurons = new ArrayList<INeuron>()
。但这似乎只是将同样的错误转移到了班级的不同部分。
我不明白为什么因为INeuron是神经元的一个子类型,所以不能隐含地将神经元强加给神经元。
答案 0 :(得分:8)
您需要使用:
public interface Layer
{
public ArrayList<? extends Neuron> getNeurons();
}
因为缺乏协方差和仿制药的逆转。如果返回一个ArrayList&lt; INeuron&gt;作为ArrayList&lt; <神经元>然后你可能能够将一个不是INeuron的元素(像神经元的另一个孩子)添加到ArrayList&lt; INeuron&gt;
答案 1 :(得分:4)
简单地改变:
ArrayList<INeuron> neurons = new ArrayList<INeuron>();
为:
ArrayList<Neuron> neurons = new ArrayList<Neuron>();
能够同时服务这两种类型。
答案 2 :(得分:2)
这是可能发生的坏事的一个例子。
void mymethod ( ILayer l )
{
List<Neuron> neurons = l . getNeurons ( ) ;
neurons . add ( new ONeuron ( ) ) ; // bad thing
}
我的方法mymethod
刚刚污染了ILayer
的{{1}}列表,其中包含非neurons
。
答案 3 :(得分:0)
public Layer <?> getNeurons();
这是编写子类型的另一种方法,对吗?