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

发布于 2024-12-11 05:37:42 字数 1111 浏览 2 评论 0原文

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

public HashSet getNeighbour();

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

<代码>public HashSet; getNeighbour();

(在 NodeFunction 类中反之亦然)。

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

public HashSet; getNeighbour();

然后在 NodeVariable 和 NodeFunction 中的方法上出现错误:

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

这不太清楚。

我发现:

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

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

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

public HashSet getNeighbour();

因此编译器不再抱怨。

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

I have an interface Node that asks for the method:

public HashSet getNeighbour();

NodeVariable implements Node, and its neighbours are of type NodeFunction (that implements Node, too), and I wrote the method:

public HashSet<NodeFunction> getNeighbour();

(and viceversa in NodeFunction class).

I found out that if I change the signature of method in Node to:

public HashSet<Node> getNeighbour();

then on the methods in NodeVariable and NodeFunction I get the error:

Error getNeighbour() in factorgraph.NodeFunction cannot implement getNeighbour() in factorgraph.Node return type java.util.HashSet is not compatible with java.util.HashSet NodeFunction.java

This is not really clear.

I found:

Overriding return type in extended interface - Bad idea?

and

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

and now I changed the Node method signature in:

public HashSet<? extends Node> getNeighbour();

thus the compiler stops complaining.

Is it right? Why HashSet is not considered like an "extension" of HashSet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

椵侞 2024-12-18 05:37:42

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

public Set getNeighbour();

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

public Set<? extends Node> getNeighbour();

First, it's a better idea to define the methods in your interfaces in terms of other interfaces and not concrete implementations. What I want to say is that the getNeighbour() method should be:

public Set getNeighbour();

And since we know that it can only return Nodes (or subtypes of Node), we might as well define it like this:

public Set<? extends Node> getNeighbour();
江南烟雨〆相思醉 2024-12-18 05:37:42

HashSetHashSet 不兼容,即使 NodeFunction 实现/子类 Node 也是如此。同样,ListList 都不是。 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之外,所有内容在语义/语法上都是有效的。 getNeighbour(){}。 Java 教程涵盖了问题。

HashSet<Node> and HashSet<NodeFunction> aren't compatible, even though NodeFunction implements/subclasses Node. Similarly, neither are List<Number> and List<Integer>. Integer subclasses Number.

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

If the compiler allowed what your trying to do, then I could do the following and a ClassCastException would be thrown, which is the exact reason generics was created.

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

Everything is semantically/syntactically valid except public Set<NodeFunction> getNeighbour(){}. The Java tutorials cover this issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文