接口

时间:2015-05-03 00:16:17

标签: java abstract-class

首先,在java中很新,对不起,如果这是一个简单的问题。

我已经实现了一个抽象类,以及两个扩展它的类。

public abstract class Lado{
//body
}

以及另外两个具有此表单的类,例如

public class Arista extends Lado
{ //body
}

所以,没有问题,现在我有一个这样定义的接口。

public interface Grafo
{  //body
   public List<Lado> lados();
   //more body
}

你看到界面返回Lado类的List, 但在我的实现中,我需要返回Arista类的List或第二类(在接口的另一个实现上)

在我必须用于接口实现的代码库中的

有像这样的lados()的实现

    public List<Lado> lados() {
        return lados;
    }

在我的代码中定义了lados,如

   private List<Arista> lados;

并初始化

  lados = new LinkedList<Arista>();

现在当然返回给出错误

GrafoNoDirigido.java:141: error: incompatible types
    return lados;
           ^
   required: List<Lado>
   found:    List<Arista>
1 error

我似乎无法在不修改提供给我的基本代码的情况下找到如何解决这个问题(我重复一下也无法改变它)。我知道我无法实例化一个抽象类对象,抽象类实现具有抽象类不具备的值和函数。

此外,我无法使用覆盖,原因与我在实现中无法更改函数签名的原因相同。

感谢您的帮助,谢谢。

如果有什么事情变得怪异,请告诉我。

-------------------- EDIT --------- Lado抽象类。

public abstract class Lado
{
   private String id;
   private double peso;

   public Lado(String id, double peso) {
      this.id = id;
      this.peso = peso;
   }

   public String getId() {
      return id;
   }

   public double getPeso() {
        return peso;
   }

   public abstract String toString();

 }

Arista亚类

public class Arista extends Lado
{
   private Vertice u;
   private Vertice v;

   public Arista(String id, double peso, Vertice u, Vertice v){
      super(id , peso);
      this.u = u;
      this.v = v;
   }

   public Vertice getExtremo1() {
     return u;
   }

   public Vertice getExtremo2() {
     return v;
   }


   public String toString() {
     String s = "string";
     return s;
   }

}

然后如果我返回List<Lado>如果你尝试做getExtremo1()它确实在编译时找到符号(Lado类上没有存在),试图像{{1}那样强制转换输出列表但它也没有正常工作。

5 个答案:

答案 0 :(得分:1)

由于Artista类也是Lado类,因此初始化应为

   .factory('FooResource', function($resource) {

    var foo = $resource('/api/foo').get();

    return foo;

   })

答案 1 :(得分:0)

尝试将您的界面更改为:

public List lados();

public List<? extends Lado> lados();

- 或 -

您可以转到另一条路线,并使列表具有子实例的父类型:

private List<Lado> lados;

@Override
public List<Lado> lados() {
    // Type of lados is List<Lado>, but we will fill it up with Arista instances...
    lados = new LinkedList<Lados>();
    lados.add(new Arista());
    // if Arista has methods that follow the with setter stereotype, ie: public Arista withId(int id) { this.setId(id); return this; } you can in-line create them:
    lados.add(new Arista()
              .withId(id)
              .withName(name)
    );
    Arista arista = new Arista();
    lados.add(arista);
    ...
    return lados;
}

希望有所帮助!

答案 2 :(得分:0)

问题在于Java并没有对&#34; variance&#34;提供良好的支持。对于枚举(不,它不是一个简单的问题)。在这里看看&#34; The Workaround&#34;解决方案:https://schneide.wordpress.com/tag/upcast/

答案 3 :(得分:0)

如果您无法更改方法返回类型或变量声明,则可以返回副本:

public List<Lado> lados() {
    return new LinkedList<Lado>(lados);
}

或者你可以返回一个包装器:

public List<Lado> lados() {
    return java.util.Collections.unmodifiableList(lados);
}

答案 4 :(得分:-1)

所以这些是你的约束:

  • 您无法更改lados()方法的返回类型(List<Lado>)。
  • 您希望自己的字段属于List<Arista>

<强> 1。复制数组

public List<Lado> lados() {
    return new ArrayList<>(lados);
}

<强> 2。将其包装为不可修改的列表*

public List<Lado> lados() {
    return Collections.unmodifiableList(lados);
}

第3。键入擦除,不要这样做,这是不安全的

在返回之前删除字段的泛型。不安全,因为如果有人添加了一个扩展Lado的对象,但它不是Arista到该列表,那么您将HeapPolution

@SuppressWarnings("unchecked")
public List<Lado> lados() {
    return (List)lados;
}