0

我有一个接口节点,它要求方法:

public HashSet getNeighbour();

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

public HashSet<NodeFunction> getNeighbour();

(在 NodeFunction 类中反之亦然)。

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

public HashSet<Node> getNeighbour();

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

factorgraph.NodeFunction 中的错误 getNeighbour() cannot implement getNeighbour() in factorgraph.Node return type java.util.HashSet is not compatible with java.util.HashSet NodeFunction.java

这不是很清楚。

我发现:

在扩展接口中覆盖返回类型 - 坏主意?

Java - 当返回类型对自己的方法参数类型使用泛型时,覆盖扩展接口的返回类型

现在我更改了 Node 方法签名:

public HashSet<? extends Node> getNeighbour();

因此编译器停止抱怨。

这样对吗?为什么 HashSet 不被视为 HashSet 的“扩展”?

4

2 回答 2

1

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

public Set getNeighbour();

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

public Set<? extends Node> getNeighbour();
于 2011-10-23T15:56:26.770 回答
0

HashSet<Node>并且HashSet<NodeFunction>不兼容,即使NodeFunctionimplements/subclasses Node。同样,也不是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抛出 a,这就是创建泛型的确切原因。

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 教程涵盖了这个问题。

于 2011-10-23T17:20:31.250 回答