0

メソッドを要求するインターフェース 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 と互換性がありません

これは本当に明確ではありません。

私が見つけた:

拡張インターフェイスで戻り値の型をオーバーライドする - 悪い考えですか?

Java - 戻り値の型が独自のメソッド パラメータ型にジェネリックを使用する場合、拡張インターフェイスの戻り値の型をオーバーライドする

そして今、Node メソッドの署名を次のように変更しました。

public HashSet<? extends Node> getNeighbour();

したがって、コンパイラは不平を言うのをやめます。

そうですか?HashSet が HashSet の「拡張」と見なされないのはなぜですか?

4

2 に答える 2

1

まず、具体的な実装ではなく、他のインターフェイスの観点からインターフェイスのメソッドを定義することをお勧めします。私が言いたいのは、getNeighbour()メソッドは次のようにする必要があるということです。

public Set getNeighbour();

ノード (またはノードのサブタイプ) のみを返すことができることがわかっているので、次のように定義することもできます。

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

HashSet<Node>実装/サブクラスHashSet<NodeFunction>であっても、互換性がありません。同様に、 と もありません。サブクラス。NodeFunctionNodeList<Number>List<Integer>IntegerNumber

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 チュートリアルでは、この問題について説明しています。

于 2011-10-23T17:20:31.250 に答える