简体   繁体   English

返回子类时方法的返回类型不兼容

[英]Incompatible return types for method when returning subclass

I am trying to define a method to return all neighbours of a given vertex on a graph given by the signature我正在尝试定义一种方法来返回由签名给出的图形上给定顶点的所有邻居

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

I wish to override this method from my KTree class which extends the above GraphClass as follows我希望从扩展上述 GraphClass 的 KTree 类中重写此方法,如下所示

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

Which gives me the following error这给了我以下错误

Incompatible types.不兼容的类型。 found 'java.ustil.ArrayList>', required 'java.ustil.ArrayList'找到'java.ustil.ArrayList>',需要'java.ustil.ArrayList'


The KVertex class also extends the original Vertex class where the .getAdjList() method is found 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;
        }
    }

My assumption when writing this method was that returning a subclass of that type should still be a valid return type because of KVertex Inheriting Vertex class, and preserving the is-a relationship.我在编写此方法时的假设是,由于 KVertex 继承 Vertex 类并保留 is-a 关系,因此返回该类型的子类仍然应该是有效的返回类型。 How might I properly define the KVertex class or the getNeighbours method so that I could return a list of any subclass of Vertex.我如何正确定义 KVertex 类或 getNeighbours 方法,以便我可以返回 Vertex 的任何子类的列表。 Thank You!谢谢你!

The main problem resides in the Vertex class the method主要问题在于 Vertex 类的方法

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

implies that it will return a ArrayList<Vertex<Integer>> for your KVertex class.意味着它将为您的KVertex类返回一个ArrayList<Vertex<Integer>>

But getNeighbours(V v) wants to return an ArrayList<KVertex> which is no covariant with ArrayList<Vertex<Integer>> so this can't happen.但是getNeighbours(V v)想要返回一个与ArrayList<Vertex<Integer>>没有协变的ArrayList<KVertex>所以这不可能发生。 The is-a relationship is valid between classes, not between type variables: a List<KVertex> is-not-a List<Vertex<Integer>> . is-a关系在类之间有效,而不是在类型变量之间有效:a List<KVertex> is-not-a List<Vertex<Integer>>

A solution to your problem is to pass the real type of the Vertex to the class itself, eg:您的问题的解决方案是将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();
    }
  }

In this way you make the getAdjList return a List of the type that extends your Vertex<V> .通过这种方式,您可以让getAdjList返回扩展Vertex<V>类型的List

Hmmm... I'm not really sure, but maybe this will work...嗯......我不太确定,但也许这会奏效......

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM