返回子类

时间:2015-10-31 21:10:01

标签: java inheritance subclass extends return-type

我正在尝试定义一个方法来返回签名给出的图上给定顶点的所有邻居

public abstract class GraphClass<V extends Vertex<?>,E extends Edge<V,?>> implements UndirectedGraph<V,E>{
.
.
.
        public ArrayList<V> getNeighbors(V v) {...}
}

我希望从我的KTree类中覆盖此方法,该类扩展了上面的GraphClass,如下所示

public class KTree extends GraphClass<KVertex,KEdge> {...
    public ArrayList<KVertex> getNeighbors(KVertex v) {
            return v.getAdjList();
    }
}

这给了我以下错误

  

不兼容的类型。发现   &#39; java.ustil.ArrayList&gt;&#39;,必需   &#39; java.ustil.ArrayList&#39;

KVertex类还扩展了找到.getAdjList()方法的原始Vertex类

public class KVertex extends Vertex<Integer> {...}
 public class Vertex<V>{
        protected ArrayList<Vertex<V>> neighbours = new ArrayList<>();
        ...
        public ArrayList<Vertex<V>> getAdjList(){
            return neighbours;
        }
    }

我在编写此方法时的假设是返回该类型的子类仍应是有效的返回类型,因为KVertex继承了Vertex类,并保留了is-a关系。我如何正确定义KVertex类或getNeighbours方法,以便我可以返回Vertex的任何子类的列表。谢谢!

2 个答案:

答案 0 :(得分:1)

主要问题在于Vertex类的方法

public ArrayList<Vertex<V>> getAdjList()
{
  return neighbours;
}

表示它会为您的ArrayList<Vertex<Integer>>课程返回KVertex

getNeighbours(V v)想要返回与ArrayList<KVertex>无法协调的ArrayList<Vertex<Integer>>,因此不会发生这种情况。 is-a关系在类之间有效,而不是在类型变量之间:List<KVertex> 不是 List<Vertex<Integer>>

解决问题的方法是将Vertex的实际类型传递给类本身,例如:

  class Vertex<V, R extends Vertex<V, R>>
  {
    protected List<R> neighbours = new ArrayList<>();

    public List<R> getAdjList()
    {
      return neighbours;
    }
  }

  public abstract class GraphClass<V extends Vertex<?,?>,E extends Edge<V,?>> implements UndirectedGraph<V,E>
  {
    public abstract List<? extends V> getNeighbors(V v);
  }

  public class KVertex extends Vertex<Integer, KVertex>
  {

  }


  public class KTree extends GraphClass<KVertex,KEdge>
  {
    @Override
    public List<KVertex> getNeighbors(KVertex v)
    {
       return v.getAdjList();
    }
  }

通过这种方式,您可以getAdjList返回List类型的Vertex<V>

答案 1 :(得分:0)

嗯......我不太确定,但也许这会奏效......

public class Vertex<V>{
        protected ArrayList<Vertex<V>> neighbours = new ArrayList<Vertex<V>>();
        ...
        public ArrayList<Vertex<V>> getAdjList(){
            return neighbours;
        }
    }