Reputation: 584
I have a class hierarchy of entities and want to create a hierarchy of service interfaces for them in Java. UI components shall then access the entity-related services through interfaces:
class BaseEntity { }
class Fruit extends BaseEntity { }
class Banana extends Fruit { }
class Apple extends Fruit { }
A UI component (which is reused in multiple places in slightly different context) needs to access the Fruit service through an interface FruitService and I want to decide during runtime in which places this will be the BananaService or AppleService service interface. I thought this would be simple using generics:
interface Service<T extends BaseEntity>
{
List<T> getAll();
void save (T object);
void delete (T object);
}
// More strict interface only allowed for fruits. Referenced by UI component
interface FruitService<F extends Fruit> extends Service<Fruit> {}
// Interface only allowed for bananas
interface BananaService extends FruitService<Banana> {}
class BananaServiceImpl implements BananaService
{
// Compiler error here because expecting Fruit type:
@Override
public List<Banana> getAll()
{
}
...
}
This is however giving me the following compiler error:
The return type is incompatible with Service<Fruit>.getAll()
Why does Java not recognize that the implementation has been parametrized with Banana? I would expect the generic parameter in BananaServiceImpl to be resolved to Banana as I specified in BananaService!
Upvotes: 3
Views: 496
Reputation: 1071
interface FruitService<F extends Fruit> extends Service<Fruit> {}
should be
interface FruitService<F extends Fruit> extends Service<F> {}
That way, you pass in the generic over to the Service
Upvotes: 11