In java, is an interface providing parameters to extend a parameterized interface an exact synonym of it?

jmgonet :

I would like to use an interface as a short-name for a parameterized interface, so as to avoid polluting all the code with generic syntax. For example:

EggChicken egg = chicken.lay();  // Can't make it compile.

instead of:

Egg<AnimalChicken> egg = chicken.lay(); // Compiles happily.

Say I would like to model the animals reproduction modes Using parameterized classes (https://en.wikipedia.org/wiki/Modes_of_reproduction). I have the following interfaces:

public interface Animal<T> {
   T lay();
}

interface Viviparous<T extends Viviparous> extends Animal<T> {
}

interface Egg<T extends Oviparous> {
    T hatch();
}

interface Oviparous<T extends Oviparous> extends Animal<Egg<T>> {
}

The idea being that viviparous animals lay new instances of the same animal, whereas oviparous animals lay eggs that hatch new instances of the same animal.

Now, I would like to define more precise interfaces to describe a Dog and a Chicken:

interface AnimalDog extends Viviparous<AnimalDog> {
}

interface AnimalChicken extends Oviparous<AnimalChicken> {
}

interface EggChicken extends Egg<AnimalChicken> {
}

Finally, those are the implementations:

public class AnimalDogImpl implements AnimalDog {
    @Override
    public AnimalDog lay() {
        return new AnimalDogImpl();
    }
}

class AnimalChickenImpl implements AnimalChicken {
    @Override
    public EggChickenImpl lay() {
        return new EggChickenImpl();
    }
}

public class EggChickenImpl implements EggChicken {
    @Override
    public AnimalChicken hatch() {
        return new AnimalChickenImpl();
    }
}

My problem comes when I want to use the the classes in code:

public class AnimalTest {
    @Test
    public void can_do_something_nice() {
        AnimalChicken chicken = new AnimalChickenImpl();
        // Error here:
        EggChicken egg = chicken.lay();
        AnimalChicken chick = egg.hatch();
       Assertions.assertThat(chick).isNotNull();
    }
}

I get the error: Required EggChicken, found Egg<AnimalChicken>, but this is precisely how I defined EggChicken. Is it possible to solve this kind of indirection?

Thilo :

What you are looking for is called a type alias.

Java unfortunately does not have them.

When you create a new interface, that defines a new type. An instance of EggChicken is also an instance of Egg<Chicken>, but not the other way around. You would have to make your AnimalChicken (interface!) return an EggChicken explicitly.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=322653&siteId=1