Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Interface with inverse relationship

I want to create two interfaces with inverse relationships.

public interface Item <D extends Description,
                                        C extends Category<D,Item<D,C>>> {
    public C getCategory();
    public void setCategory(C category);}

I'm not sure if expression C extends Category<D,Item<D,C>> is correct, but at least there are no compiler errors.

public interface Category<D extends Description, I extends Item> {
    public List<I> getItems();
    public void setItems(List<I> items);}

I extends Item gives the warning Item is a raw type. References to Item<D,C> should be parametrized. I tried

I extends Item<D,Category<D,I>>

but this results in the error 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>. How to I parametrize the interface Category correctly with generics?

like image 620
Thor Avatar asked Aug 09 '11 12:08

Thor


People also ask

What is a generic interface?

A generic interface is primarily a normal interface like any other. It can be used to declare a variable but assigned the appropriate class. It can be returned from a method. It can be passed as argument. You pass a generic interface primarily the same way you would an interface.

Can a generic implement an interface?

Only generic classes can implement generic interfaces. Normal classes can't implement generic interfaces.


1 Answers

This seems to work :). I have no idea how to explain it ( i normally try to avoid doing stuff like that ) but here it goes:

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) {
    }
}

Now if you do this:

CustomCategory customCategory = new CustomCategory();
CustomItem customItem = new CustomItem();
DescriptionImpl description = new DescriptionImpl();

customItem.getCategory();

the type of the category returned by the customItem.getCategory() is CustomCategory which i think is what you actually want.

like image 67
Mihai Toader Avatar answered Oct 12 '22 20:10

Mihai Toader