возвращаемый тип хеш-таблицы в расширенном методе - PullRequest
0 голосов
/ 23 октября 2011

У меня есть интерфейсный узел, который запрашивает метод:

public HashSet getNeighbour();

NodeVariable реализует Node, и его соседи имеют тип NodeFunction (который также реализует Node), и янаписал метод:

public HashSet<NodeFunction> getNeighbour();

(и наоборот в классе NodeFunction).

Я обнаружил, что если я изменю сигнатуру метода в Node на:

public HashSet<Node> getNeighbour();

затем на методах в NodeVariable и NodeFunction я получаю ошибку:

Ошибка getNeighbour () в factorgraph.NodeFunction не может реализовать getNeighbour () в factorgraphТип возвращаемого узла* Переопределение типа возвращаемого значения в расширенном интерфейсе - Плохая идея?

и

Java - Переопределение возвращаемого типа расширенного интерфейса, когда тип возврата использует обобщенные значения для собственного параметра методатипы

и теперь меняюПодпись подписи метода узла в:

public HashSet<? extends Node> getNeighbour();

, таким образом, компилятор перестает жаловаться.

Это правильно?Почему HashSet не считается «расширением» HashSet?

Ответы [ 2 ]

1 голос
/ 23 октября 2011

Во-первых, лучше определить методы в ваших интерфейсах с точки зрения других интерфейсов, а не конкретных реализаций. Я хочу сказать, что метод getNeighbour() должен быть:

public Set getNeighbour();

И поскольку мы знаем, что он может возвращать только Узлы (или подтипы Узла), мы могли бы также определить его следующим образом:

public Set<? extends Node> getNeighbour();
0 голосов
/ 23 октября 2011

HashSet<Node> и HashSet<NodeFunction> несовместимы, хотя NodeFunction реализует / подклассы 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, что является точной причиной, по которой были созданы дженерики.

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 охватывают эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...