具有反比关系的通用接口

时间:2011-08-09 12:55:49

标签: java generics interface

我想创建两个具有反向关系的接口。

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进行参数化?

5 个答案:

答案 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?

再一次,我们必须依靠程序员的纪律,不要做那样的事情。