补充通用类

时间:2017-04-15 12:45:08

标签: java generics generic-programming

我有两个抽象类: 容器,节点

一种Container将始终包含相同类型的Node,并且一种节点将仅属于其对应的容器: NodeTypeA存储在ContainerTypeA中,并且其中没有其他Node子类存储在其中。 NodeTypeB存储在ContainerTypeB中,并且其中没有其他Node子类存储在其中。从Node到其Container的反向引用也应该知道Container的类型,因此关系是双向的。

我在使用Java实现它时遇到了问题。

我这样做:

Container<C extends Container<C,N>, N extends Node<C,N>>
Node<C extends Container<C,N>, N extends Node<C,N>>

但是,当我在Container中定义以下字段时,出现错误:

private List<N> nodes;

错误消息说我应该用Node替换N.这对我来说似乎是多余的。为什么会发生这种情况,如何让程序理解

N

应该等于

Node<C,N>

测试用例:

https://ideone.com/wam0gi

背后的目的:

有许多不同类型的节点和许多不同类型的节点可以互动。但是,他们有一些共同的主题。 Container和Node应该是抽象类,我可以在其中定义方法和抽象方法来定义这些常见主题。然后,ContainerA和NodeA将定义一种特定的交互方法。我使用泛型是因为如果我的IDE足够智能以便知道ContainerA中的任何Node总是NodeA,并且NodeA的所有者总是ContainerA,那么编程变得容易得多,所以我可以避免一些不必要的类型转换

(注意:这个问题类似但不等于Complementary generic types

2 个答案:

答案 0 :(得分:1)

除了几个微不足道的错误(abstract应该在java class之前,错误的类型变量L在第16行的Node的构造函数中,尝试访问私有字段在第18行,你的语义问题在第18行。this的类型是Node<C,N>,而不是N

实现目标的一种方法是向Node添加一个返回N的抽象方法,所有子类将通过返回this来实现它。

abstract protected N me();

然后,一旦您为Container添加了适当的设置器,您就会将第18行更改为

owner.add( me() );

答案 1 :(得分:1)

  

如何让程序理解这一点   N应该等于Node<C,N>

他们并不平等。 N 延伸 Node<C, N>

private List<N> nodes;

表示Node<C, N>的某些子类的列表。

添加到此类列表时会遇到困难。

考虑

List<N> nodes = ...;

Node<C, N> node = new Node<>(...);
nodes.add(node);  // ERROR because node might not be the right subclass

VS

List<Node<C, N>> nodes = ...;

Node<C, N> node = new Node<>(...);
nodes.add(node);  // OK.

VS

List<N> nodes = ...;
N node = new Node<C, N>(...);   // ERROR.  Not all Node<C, N> are N
// N is a sub-type not a super-type of Node<C, N>
nodes.add(node);

如果Node是最终的,你说它不是,&#34;&#34;&#34;

  

有许多不同类型的节点

&#34;&#34;&#34;,然后你可以做

N node = (N) new Node<C, N>(..);  // Unchecked conversion

但即使在程序的上下文中它是安全的,这种类型擦除规则的修改也是不必要的。