Reputation: 2311
I am a generics newbie and I am not able to find out the best way to achieve this. Please feel free to point out if I am doing something obviously wrong.
interface Node<T> {
void addOne(Node<T> node);
}
class StringNode implements Node<String> {
List<StringNode> data = new ArrayList<>();
/**
* {@inheritDoc}
*/
@Override
public void addOne(Node<String> node) {
StringNode stringNode = (StringNode) node;
data.add(stringNode);
}
}
I was hoping to find a way to avoid the downcast from Node to StringNode in the implementation of addOne by having the function itself be of signature public void addOne(StringNode node). Any ideas as to how the definition of Node can be changed to achieve this for any implementation of the interface?
I tried searching through the questions already asked, but was not able to find a close match. Any pointers to questions where this has already been discussed would also be greatly appreciated.
Thanks in advance!
Upvotes: 3
Views: 978
Reputation: 1221
This is how I would have done it:
interface Node<T extends Node<T>> {
void addOne(T node);
}
class StringNode implements Node<StringNode> {
List<StringNode> data = new ArrayList<StringNode>();
/**
* {@inheritDoc}
*/
@Override
public void addOne(StringNode node) {
data.add(node);
}
}
Similar to U-No-Poo's suggestion, but a little more strict (forces T to actually be a node)
Upvotes: 2
Reputation: 2859
You could introduce another generic parameter:
public interface Node<VALUE_TYPE, SELF> {
public void addOne(SELF u);
}
public class StringNode implements Node<String, StringNode> {
@Override
public void addOne(StringNode u) {
// TODO Auto-generated method stub
}
}
Use VALUE_TYPE
whenever you need the actual value type (in this case String) and SELF
whenever you want to pass a node of that type.
Upvotes: 1
Reputation: 2327
Why are you using String and StringNode separatly? Couldn't you just say
interface Node<T> {
void addOne(T node);
}
class StringNode implements Node<StringNode> {
List<StringNode> data = new ArrayList<StringNode>();
/**
* {@inheritDoc}
*/
@Override
public void addOne(StringNode node) {
StringNode stringNode = node;
data.add(stringNode);
}
}
Upvotes: 3