如何对多个耦合对象使用泛型?
How to use generics with multiple coupled objects?
所以我无法围绕正确的设计来解决这个问题。
我的应用程序有两个控制状态的关键对象,它们需要相互交互:ItemList、ItemState。它们都依赖于一个通用的 ITEM_TYPE,因此它们可以在不同的上下文中发挥作用。它们也是抽象的,以允许 ITEM_TYPE 依赖行为。
这两部分都需要知道通用类型,而且,由于它们相互通信,因此它们需要知道彼此的通用类型。 (一个 ItemList< String > 实例需要知道它的 ItemState 字段是一个 ItemState< String > ,反之亦然)。
我目前的解决方案有效,但看起来很糟糕。一定有更好的方法。这就是我现在正在做的事情:
public abstract class ItemState<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
public abstract class ItemList<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
然后一个实施 class 可能看起来像:
class StringState extends ItemState<String, StringState, StringList> {
}
class StringList extends ItemList<String, StringState, StringList> {
}
请注意,对于 ItemState,STATE_TYPE 是对实现 class 的引用,对于 ItemList/LIST_TYPE.
也是如此
如果我只是让 ItemState 成为 ItemList 的内部 class,我的问题真的会得到解决,因为会有一个隐式绑定并且它们可以共享通用声明,但是两个 classes 都太大了和独立的,我不想这样做。
有什么建议吗?
编辑:作为评论的反例:
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList getItemList();
public void doSomething() {
// This should not compile because abstract super class has
// no idea what the generic type of getItemList() is
ITEM_TYPE item = this.getItemList.getItem();
}
}
编辑 2:我认为我能想到的最佳解决方案就是让 ItemList/ItemState 以一种或另一种方式继承,这样它们就可以像 class 一样发挥作用。我不喜欢这个解决方案,因为它覆盖了关注点分离,但它使泛型更易于管理。
旁注:我的实际应用程序有 4 个交织在一起的问题 classes,为了简单起见,我只使用了 2 个。实际上,泛型非常糟糕,难以理解且难以重构(每个 class 大约有 4 整行泛型声明)。我现在已经把这4个class变成了垂直继承层次
JM Yang 的解决方案很好
我认为您在声明这 2 个 类 时可能只是引用泛型类型 ITEM_TYPE。
我能够正确编译以下代码。
public abstract class ItemList<ITEM_TYPE> {
public abstract ItemState<ITEM_TYPE> getState();
public abstract ITEM_TYPE getItem();
}
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList<ITEM_TYPE> getItemList();
public void doSomething() {
ITEM_TYPE item = getItemList().getItem();
System.out.println(item);
}
}
public class StringList extends ItemList<String> {
@Override
public StringState getState() {
return new StringState();
}
@Override
public String getItem() {
return "";
}
}
public class StringState extends ItemState<String> {
@Override
public StringList getItemList() {
return new StringList();
}
}
所以我无法围绕正确的设计来解决这个问题。
我的应用程序有两个控制状态的关键对象,它们需要相互交互:ItemList、ItemState。它们都依赖于一个通用的 ITEM_TYPE,因此它们可以在不同的上下文中发挥作用。它们也是抽象的,以允许 ITEM_TYPE 依赖行为。
这两部分都需要知道通用类型,而且,由于它们相互通信,因此它们需要知道彼此的通用类型。 (一个 ItemList< String > 实例需要知道它的 ItemState 字段是一个 ItemState< String > ,反之亦然)。
我目前的解决方案有效,但看起来很糟糕。一定有更好的方法。这就是我现在正在做的事情:
public abstract class ItemState<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
public abstract class ItemList<
ITEM_TYPE,
STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {
}
然后一个实施 class 可能看起来像:
class StringState extends ItemState<String, StringState, StringList> {
}
class StringList extends ItemList<String, StringState, StringList> {
}
请注意,对于 ItemState,STATE_TYPE 是对实现 class 的引用,对于 ItemList/LIST_TYPE.
也是如此如果我只是让 ItemState 成为 ItemList 的内部 class,我的问题真的会得到解决,因为会有一个隐式绑定并且它们可以共享通用声明,但是两个 classes 都太大了和独立的,我不想这样做。
有什么建议吗?
编辑:作为评论的反例:
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList getItemList();
public void doSomething() {
// This should not compile because abstract super class has
// no idea what the generic type of getItemList() is
ITEM_TYPE item = this.getItemList.getItem();
}
}
编辑 2:我认为我能想到的最佳解决方案就是让 ItemList/ItemState 以一种或另一种方式继承,这样它们就可以像 class 一样发挥作用。我不喜欢这个解决方案,因为它覆盖了关注点分离,但它使泛型更易于管理。
旁注:我的实际应用程序有 4 个交织在一起的问题 classes,为了简单起见,我只使用了 2 个。实际上,泛型非常糟糕,难以理解且难以重构(每个 class 大约有 4 整行泛型声明)。我现在已经把这4个class变成了垂直继承层次
JM Yang 的解决方案很好
我认为您在声明这 2 个 类 时可能只是引用泛型类型 ITEM_TYPE。
我能够正确编译以下代码。
public abstract class ItemList<ITEM_TYPE> {
public abstract ItemState<ITEM_TYPE> getState();
public abstract ITEM_TYPE getItem();
}
public abstract class ItemState<ITEM_TYPE> {
public abstract ItemList<ITEM_TYPE> getItemList();
public void doSomething() {
ITEM_TYPE item = getItemList().getItem();
System.out.println(item);
}
}
public class StringList extends ItemList<String> {
@Override
public StringState getState() {
return new StringState();
}
@Override
public String getItem() {
return "";
}
}
public class StringState extends ItemState<String> {
@Override
public StringList getItemList() {
return new StringList();
}
}