Gianni Spear
Gianni Spear

Reputation: 7936

java interface avoid casting

I have two classes. An interface class "Node" and "Nodegraph" that implements "Node". "Node" has one parametric method, add, where I use Node node as paramenter. In NodeGraph, I need to casting (NodeGraph) node in order to use NodeGraph object. Is there a better way to avoid casting?

import java.util.Set;

public interface Node {
    public String getId();
    public void add(Node node);
    public boolean remove(Node node);
}


import java.util.Iterator;
import java.util.LinkedList;

public class NodeGraph implements Node {

    private int row;
    private int column;
    private String id;
    private LinkedList<NodeGraph> neighbourds = new LinkedList<NodeGraph>();

    public NodeGraph(int row, int column) {
        this.row = row;
        this.column = column;
        id = "" + row + column;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void add(Node node) {
        neighbourds.add((NodeGraph) node);
    }

    @Override
    public boolean remove(Node node) {
        return neighbourds.remove((NodeGraph) node);
    }

}

Upvotes: 1

Views: 824

Answers (3)

tsolakp
tsolakp

Reputation: 5948

I assume you have valid reasons to keep neighbourds list bound to NodeGraph type. If so here is how you can avoid casting by parametrizing the Node interface:

public interface Node< T extends Node<T> > {
    public String getId();
    public void add(T node);
    public boolean remove(T node);
}

public class NodeGraph implements Node<NodeGraph> {

    private int row;
    private int column;
    private String id;
    private LinkedList<NodeGraph> neighbourds = new LinkedList<NodeGraph>();

    public NodeGraph(int row, int column) {
        this.row = row;
        this.column = column;
        id = "" + row + column;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void add(NodeGraph node) {
        neighbourds.add(node);
    }

    @Override
    public boolean remove(NodeGraph node) {
        return neighbourds.remove(node);
    }
}

Upvotes: 4

Costi Ciudatu
Costi Ciudatu

Reputation: 38195

You should declare the neighbors list using the interface (for both List and Node):

private List<Node> neighbourds = new LinkedList<>();

Upvotes: 2

AlexITC
AlexITC

Reputation: 1074

That happens because you neighbourds list is invariant, this means that you could insert the parametrized type only, which is NodeGraph in this case, defining the list as covariant to Node would let you add any subclass of Node:

private LinkedList<? extends Node> neighbourds = new LinkedList<>();

Upvotes: 3

Related Questions