我想创建两个具有反向关系的接口。
public interface Item <D extends Description,
C extends Category<D,Item<D,C>>> {
public C getCategory();
public void setCategory(C category);}
我不确定表达式C extends Category<D,Item<D,C>>
是否正确,但至少没有编译器错误。
public interface Category<D extends Description, I extends Item> {
public List<I> getItems();
public void setItems(List<I> items);}
I extends Item
会发出警告Item is a raw type. References to Item<D,C> should be parametrized
。我试过了
I extends Item<D,Category<D,I>>
但这会导致错误Bound mismatch: The type Category<D,I> is not a valid substitute for the bounded parameter <C extends Category<D,Item<D,C>>> of the type Item<D,C>
。如何使用泛型正确地对接口Category
进行参数化?
答案 0 :(得分:2)
这似乎有效:)。我不知道如何解释它(我通常会尽量避免做那样的事情),但在这里:
interface Description {}
interface Item<D extends Description, I extends Item<D, I, C>, C extends Category<D, C, I>>
{
public C getCategory();
public void setCategory(C category);
}
interface Category<D extends Description, C extends Category<D, C, I>, I extends Item<D, I, C>> {
public List<I> getItems();
public void setItems(List<I> items);
}
class DescriptionImpl implements Description {}
class CustomItem implements Item<DescriptionImpl, CustomItem, CustomCategory> {
public CustomCategory getCategory() {
return null;
}
public void setCategory(CustomCategory category) {
}
}
class CustomCategory implements Category<DescriptionImpl, CustomCategory, CustomItem> {
public List<CustomItem> getItems() {
return null; }
public void setItems(List<CustomItem> items) {
}
}
现在,如果你这样做:
CustomCategory customCategory = new CustomCategory();
CustomItem customItem = new CustomItem();
DescriptionImpl description = new DescriptionImpl();
customItem.getCategory();
customItem.getCategory()
返回的类别类型是CustomCategory,我认为这是你真正想要的。
答案 1 :(得分:0)
此编译没有警告:
interface Description {}
interface Item<D extends Description, C extends Category<D, Item<D, C>>> {
public C getCategory();
public void setCategory(C category);
}
public interface Category<D extends Description, I extends Item<D, ?>> {
public List<I> getItems();
public void setItems(List<I> items);
}
我做了I extends Item<D, ?>
。虽然这没有任何警告,但这可能会给你带来其他问题 - 如果有问题请告诉我,我会看到我能做些什么。
答案 2 :(得分:0)
答案 3 :(得分:0)
让我们首先忘记描述,然后制作一些不错的对称接口:
interface Item<C extends Category<Item<C>>> {}
interface Category<I extends Item<Category<I>>> {}
对于“描述”,您可能需要两种不同的“项目”和“类别”描述类型。
更一般地说,我不确定你的设计是个好主意。我不知道你会用它做什么,但它看起来像是难以正确使用的东西。
此外,item.setCategory(c)
出现问题,因为item
已经按类别进行了参数化。
答案 4 :(得分:0)
考虑这个简化的问题
interface Item<C extends Container<Item<C>>>
interface Container<I extends Item<Container<I>>>
它不起作用,因为Container<Item<C>>
的子类型非常有限 - Container<MyItem>
不是它的子类型,就像List<string>
不是List<Object>
的子类型一样
我们可以用通配符放松它:
interface Item<C extends Container<? extends Item<C>>>
interface Container<I extends Item<? extends Container<I>>>
现在工作正常
class MyItem implements Item<MyContainer>
class MyContainer implements Container<MyItem>
居多。以下声明也是允许的,但不是我们想要的
class HerItem implements Item<MyContainer> // nooo!
这是因为我们放宽了约束。嗯,这不是一个非常严重的问题。当然,我们的类型系统并不像我们想要的那么严格(没有类型系统),但程序员会本能地遵循预期的约束,不要因为他们可以而不顾自己的方式编写奇怪的东西。
理想情况下,我们需要This
类型,我们预期的约束可以表示为
interface Item<C extends Container<This>>>
interface Container<I extends Item<This>>
由于我们没有This
,因此会尝试通过类型参数
interface Item<C extends Container<This, C>>, This extends Item<C, This> >
interface Container<I extends Item<This, I>, This extends Container<I, This>>
(或更对称
interface Item<C extends Container<I, C>>, I extends Item<C, I> >
interface Container<I extends Item<C, I>, C extends Container<I, C>>
)然而,这也不是很紧张。 This
实际上不是“这种类型”。
class HerItem implements Item<MyContainer, MyItem> // uh?
再一次,我们必须依靠程序员的纪律,不要做那样的事情。