【问题标题】:Incompatible return types for method when returning subclass返回子类时方法的返回类型不兼容
【发布时间】:2016-02-01 02:24:10
【问题描述】:

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

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();
    }
}

这给了我以下错误

不兼容的类型。成立 'java.ustil.ArrayList>',必填 'java.ustil.ArrayList'


KVertex 类还扩展了原来的 Vertex 类,在该类中找到了 .getAdjList() 方法

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 的任何子类的列表。谢谢!

【问题讨论】:

    标签: java inheritance subclass extends return-type


    【解决方案1】:

    主要问题在于Vertex类的方法

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

    暗示它将为您的KVertex 类返回一个ArrayList&lt;Vertex&lt;Integer&gt;&gt;

    但是getNeighbours(V v) 想要返回一个与ArrayList&lt;Vertex&lt;Integer&gt;&gt; 没有协变的ArrayList&lt;KVertex&gt;,所以这不会发生。 is-a 关系在类之间有效,在类型变量之间无效:List&lt;KVertex&gt; is-not-a List&lt;Vertex&lt;Integer&gt;&gt;

    解决问题的方法是将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 返回一个扩展您的Vertex&lt;V&gt; 类型的List

    【讨论】:

      【解决方案2】:

      嗯...我不太确定,但也许这会起作用...

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-15
        • 1970-01-01
        • 1970-01-01
        • 2012-05-08
        • 1970-01-01
        • 2014-04-18
        • 2011-07-13
        • 2014-08-29
        相关资源
        最近更新 更多