返回子类时方法的返回类型不兼容 [英] Incompatible return types for method when returning subclass

查看:273
本文介绍了返回子类时方法的返回类型不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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) {...}
}

我希望从我的KTree类中重写此方法,该类对上述GraphClass进行了如下扩展

I wish to override this method from my KTree class which extends the above GraphClass as follows

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

哪个给我以下错误

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

Incompatible types. found 'java.ustil.ArrayList>', required 'java.ustil.ArrayList'


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


The KVertex class also extends the original Vertex class where the .getAdjList() method is found

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


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. How might I properly define the KVertex class or the getNeighbours method so that I could return a list of any subclass of Vertex. Thank You!

推荐答案

主要问题在于Vertex类中的方法

The main problem resides in the Vertex class the method

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

表示它将为您的KVertex类返回ArrayList<Vertex<Integer>>.

implies that it will return a ArrayList<Vertex<Integer>> for your KVertex class.

但是getNeighbours(V v)想要返回与ArrayList<Vertex<Integer>>没有协变的ArrayList<KVertex>,因此不会发生这种情况. is-a关系在类之间有效,而在类型变量之间无效:List<KVertex> is-not-a List<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. The is-a relationship is valid between classes, not between type variables: a List<KVertex> is-not-a List<Vertex<Integer>>.

您的问题的一种解决方案是将Vertex的真实类型传递给类本身,例如:

A solution to your problem is to pass the real type of the Vertex to the class itself, eg:

  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<V>的类型的List.

In this way you make the getAdjList return a List of the type that extends your Vertex<V>.

这篇关于返回子类时方法的返回类型不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆