我有两个抽象类:
容器,节点
一种容器将始终包含相同类型的节点,而一种节点将仅属于其对应的容器:
NodeTypeA存储在ContainerTypeA中,并且没有其他Node子类存储在其中。
NodeTypeB存储在ContainerTypeB中,并且没有其他Node子类存储在其中。从节点到其容器的反向引用也应该知道容器的类型,因此关系是双向的。
我在用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
其目的是:
有许多不同种类的节点以及它们可以交互的许多不同方式。但是,它们具有一些共同的主题。容器和节点应该是抽象类,在其中我可以定义方法和抽象方法来定义这些通用主题。然后,ContainerA和NodeA将一起定义一种特定的交互方法。我之所以使用泛型,是因为如果我的IDE足够聪明,可以知道ContainerA中的任何节点始终是NodeA,而NodeA的所有者始终是ContainerA,则编程会容易得多,因此可以避免不必要的类型转换。
(注意:这个问题是相似的,但不等于Complementary generic types)
最佳答案
除了几个琐碎的错误(Java中的abstract
应该在class
之前,第16行的L
的构造函数中错误的类型变量Node
尝试在第18行访问私有字段)之外,您的语义问题也位于第18. this
的类型是Node<C,N>
,而不是N
。
实现目标的一种方法是向Node
添加一个抽象方法,该方法返回N
,所有子类都将通过返回this
来实现它。
abstract protected N me();
然后,向
Container
添加适当的设置器后,将第18行更改为owner.add( me() );