如何使用Java泛型来避免覆盖继承的方法(类似模板的行为)?

时间:2013-01-04 11:13:23

标签: java templates generics inheritance

我想在Java中创建一个包含节点的图表。图表类将由不同的人和不同的算法使用,因此我们将需要针对每种情况使用不同的Node类,例如DefaultNodeSpecialNode extends DefaultNode

现在我希望DefaultNode包含Node需要工作的所有常规内容,例如直接邻居列表。所以我在DefaultNode中实现了这个列表:

List<DefaultNode> neighbours = new ArrayList<DefaultNode>();

我现在的问题是,我显然还需要SpecialNode类中的这个列表,但它应该包含并返回SpecialNodes。当然,我可以覆盖从addNeighbour()继承的每个类中的列表和getNeighbours()以及DefaultNode方法,但这似乎是多余的,而不是OOP的工作方式。我认为这将是一个使用模板的完美案例(比如在C ++中),但是afaik在Java中没有这样的构造,让我们留下了Generics。

我到目前为止提出的解决方案如下:

interface INode {}

class DefaultNode<T extends INode> implements INode {

    List<T> neighbours;

    List<T> getNeighbours(){}

    void addNeighbour(T node){}

}

这里,<T extends INode>括号描述了该节点的可能邻居。所以对于SpecialNode,我会这样做:

class SpecialNode extends DefaultNode<SpecialNode> {}

现在,虽然这似乎按预期工作,但有点奇怪......我很惊讶我找不到更容易的解决方案,因为这种情况似乎比较常见。你怎么解决这个问题?我错过了更好/更简单的方法吗?或者以上是一种可行的方法吗?

2 个答案:

答案 0 :(得分:2)

你的方法没有错。事实上,一些标准接口,例如Comparable,就是以这种方式定义的:

public class Fruit implements Comparable<Fruit> {
             ^^^^^                       ^^^^^

答案 1 :(得分:-1)

如果要强制节点的邻居属于同一类型,可以使用:

class DefaultNode<T extends DefaultNode<T>> implements INode

虽然我会使接口通用(并且只称它为Node而不是INode)。