用 List<?> 成员定义抽象泛型类
Posted
技术标签:
【中文标题】用 List<?> 成员定义抽象泛型类【英文标题】:Defining abstract generic class with List<?> members 【发布时间】:2016-02-14 11:51:16 【问题描述】:即使为此想出一个干净的标题也是一个挑战。
基本思想是定义两个超类:一个用于“子”项,其成员引用其“父”,另一个用于包含子对象的“父”列表。 child->parent 和 parent->child 的链接是对称的。每个父/子超类都有定义和实现附加功能的子类。总是有一个并行的子类,这样child<A>
与parent<A>
配对。也就是说,parent<A>
将仅包含 child<A>
引用,而 child<A>
将仅引用 parent<A>
- 子类型之间没有“交叉”。
我该如何表示?我已经坚持了好几天了,我对多层嵌套泛型类型越有创意,它就越糟糕。这就是我想做的:
abstract class ChildBase<T extends ChildBase<T>>
ParentBase<T> parent;
abstract class ParentBase<T extends ChildBase<T>>
LinkedList<T> childList;
class ChildSub extends ChildBase<ChildSub>
// ... class specific stuff
class ParentSub extends ParentBase<ChildSub>
// ... class specific stuff
这是一团糟。我怀疑有一种更简单、直接的方法可以做到这一点,而且可能是完全不同的方向。
【问题讨论】:
我很想知道您为什么需要T
来扩展ChildBase
?这些类中是否会有一些方法要求它们是ChildBase
?获取节点的兄弟姐妹就是一个例子。如果没有,那么您可以显着简化结构。
正如@sprinter 所说,也许需要深入了解您的问题域才能提供更好的设计。考虑更详细地描述所描述的类的应用。
您是否尝试过寻找基于接口的解决方案而不是继承?就我个人而言,我发现如果你只是解耦类而不是更多地耦合它们,很多这些问题会更容易解决。
【参考方案1】:
你的意思是class ParentSub extends ParentBase<ChildSub>
?
如果您进行这一更改,则一切都会编译。
这是一团糟。我怀疑有一种更简单、直接的方法可以做到这一点,而且可能是完全不同的方向。
实际上,与我见过的其他一些使用泛型的方式相比,这并没有那么糟糕。没有完全不同的方法可以实现您所缺少的。
唯一的选择(我认为你应该认真考虑)是使 ChildBase
和 ParentBase
非泛型,并在必要时使用强制转换。泛型被引入到语言中,以帮助程序员编写正确的、类型安全的程序。当您的类之间存在复杂或循环的关系时,弄清楚如何正确使用泛型变得如此困难和耗时,以至于根本没有使用它们的好处。
【讨论】:
是的,我已经尝试将特定类型的内容添加到子类中(而不是在类之外进行强制转换)。我看到的权衡是在维护中。当需要更改时,我需要更加努力地确保根据需要将它们传播到所有子类;确实,花在循环/嵌套通用方法工作上的时间是浪费的,并且可能导致脆弱的代码在我每次需要更改时都会中断。 @ags 模式MyClass<T extends MyClass<T>>
的一个问题(除了非常混乱之外)是它非常严格,因为它不能很好地与继承混合。 (***.com/questions/33632871/…)。如果您将来决定扩展ChildSub
,您将面临更严重的问题,因为您已经将类型参数固定为ChildSub
。【参考方案2】:
我花了一点时间来分析你有什么,我真的不明白有什么问题。你的定义似乎工作得很好。这到底是怎么一团糟?
将您拥有的内容扩展到更具体的内容,例如:
abstract class Child<T extends Child<T>>
private final Parent<T> parent;
protected Child(Parent<T> parent)
this.parent = parent;
Parent<T> getParent()
return this.parent;
abstract class Parent<T extends Child>
private final LinkedList<T> children = new LinkedList<>();
void addChild(T child)
this.children.add(child);
List<? extends T> getChildren()
return Collections.unmodifiableList(this.children);
我可以很容易地表达你说你想要表达的想法:
class Daedalus extends Parent<Icarus>
class Icarus extends Child<Icarus>
public Icarus(Parent<Icarus> parent)
super(parent);
然后做
Daedalus parent = new Daedalus();
Icarus child = new Icarus(parent);
parent.addChild(child);
for(Icarus aChild : parent.getChildren())
//do something with aChild
我一点也不觉得这很乱,从你的问题中我也不清楚为什么这会是一个问题。
【讨论】:
以上是关于用 List<?> 成员定义抽象泛型类的主要内容,如果未能解决你的问题,请参考以下文章