Reputation: 90
I want to make a Graph consiting of Nodes in Java. The graph class will be used by different people and different algorithms, so we will need different Node classes for each case, let's say DefaultNode
and SpecialNode extends DefaultNode
.
Now I want DefaultNode
to contain all the general stuff that a Node needs to work, like for example a list of direct neighbours. So I implement this list in DefaultNode
:
List<DefaultNode> neighbours = new ArrayList<DefaultNode>();
My problem is now, that I obviously also need this list in the SpecialNode
class, but there it should contain and return SpecialNodes. Of course I could overwrite the list and addNeighbour()
as well as getNeighbours()
methods in every class that inherits from DefaultNode
, but that seems redundant and not how OOP is meant to work. I think this would be a perfect case to use templates (like in C++), but afaik there is no such construct in Java, leaving us with Generics.
The solution I came up with so far is the following:
interface INode {}
class DefaultNode<T extends INode> implements INode {
List<T> neighbours;
List<T> getNeighbours(){}
void addNeighbour(T node){}
}
here, the <T extends INode>
brackets describe the possible neighbours of this node. So for a SpecialNode
I would do:
class SpecialNode extends DefaultNode<SpecialNode> {}
now, while this seems to work as intended, it kind of feels strange... I was surprised that I could not find an easier solution, as this situation seems relatively common. How would you solve this? Is there a better/simpler approach that I missed? Or is the above a viable approach?
Upvotes: 2
Views: 166
Reputation: 2976
If you want to force that the neighbours of a node are of the same type, you can use:
class DefaultNode<T extends DefaultNode<T>> implements INode
though I would make the interface generic (and just call it Node not INode).
Upvotes: -1
Reputation: 500663
There is nothing wrong with your approach. In fact, some standard interfaces, such as Comparable
are defined in exactly this way:
public class Fruit implements Comparable<Fruit> {
^^^^^ ^^^^^
Upvotes: 2