在扩展方法中返回类型哈希表

时间:2011-10-23 15:42:10

标签: java hashset extending

我有一个接口Node询问方法:

public HashSet getNeighbour();

NodeVariable实现了Node,它的邻居是NodeFunction类型(也实现了Node),我编写了方法:

public HashSet<NodeFunction> getNeighbour();

(在NodeFunction类中反之亦然)。

我发现如果我将Node中方法的签名更改为:

public HashSet<Node> getNeighbour();

然后在NodeVariable和NodeFunction中的方法我得到错误:

  

factorgraph.NodeFunction中的错误getNeighbour()无法在factorgraph.Node中实现getNeighbour()返回类型java.util.HashSet与java.util.HashSet NodeFunction.java不兼容

这不是很清楚。

我找到了:

Overriding return type in extended interface - Bad idea?

Java - Overriding return type of extended interface when return type uses generics for own method parameter types

现在我在:

中更改了Node方法签名

public HashSet<? extends Node> getNeighbour();

因此编译器停止抱怨。

是不是?为什么HashSet不被视为HashSet的“扩展”?

2 个答案:

答案 0 :(得分:1)

首先,根据其他接口而不是具体实现来定义接口中的方法更好。我想说的是getNeighbour()方法应该是:

public Set getNeighbour();

既然我们知道它只能返回Nodes(或Node的子类型),我们也可以这样定义它:

public Set<? extends Node> getNeighbour();

答案 1 :(得分:0)

即使HashSet<Node>实现/子类HashSet<NodeFunction>

NodeFunctionNode也不兼容。同样,List<Number>List<Integer>都不是。 Integer子类Number

static List<Number> getNumberList(int size) {
    //ArrayList<Integer> numList = null; //Doesn't compile
    ArrayList<Number> numList = null; //Compiles
    return numList;
}

如果编译器允许你尝试做什么,那么我可以执行以下操作并抛出ClassCastException,这就是创建泛型的确切原因。

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main( String[] args ) {
        Node nd = getInstance();
        Set<Node> ndSet = nd.getNeighbour();
        ndSet.add( new NodeSign() );
        nd.removeSingleNeighbor(); //throws ClassCastException
    }

    static Node getInstance() {
        return new NodeVariable();
    }
}

interface Node {
    public Set<Node> getNeighbour();
    public void removeSingleNeighbor();
}

class NodeVariable implements Node {
    Set<NodeFunction> ndFuncList = new HashSet<NodeFunction>();
    public Set<NodeFunction> getNeighbour(){ return ndFuncList; } //wont' compile

    //HERE!!!!

    public void removeSingleNeighbor() { 
        NodeFunction ndFunc = (NodeFunction)ndFuncList.toArray()[ndFuncList.size()-1]; //throws ClassCastException
    }
}

class NodeFunction implements Node {
    public Set<NodeFunction> getNeighbour(){ return null; } //won't compile
    public void removeSingleNeighbor() {}
}

class NodeSign implements Node {
    public Set<NodeFunction> getNeighbour(){ return null; } //won't compile
    public void removeSingleNeighbor() {}
}

除了public Set<NodeFunction> getNeighbour(){}之外,所有内容在语义/语法上都是有效的。 Java教程涵盖了this问题。