Should I specify the concrete type for generic types when extending an interface with another interface?
What I mean is, if I have an interface:
public interface Repo<T>{
Collection<T> search(String params);
T get(String id);
}
and then a whole bunch specific Repositories, like ClientRepo, CustomerRepo, etc... is it reasonable to specify the type T when extending this interface, e.g.:
public interface ClientRepo extends Repo<Client>{
}
public interface CustomerRepo extends Repo<Customer>{
}
where Client and Customer are just some classes.
Did anyone have a similar problem? I mean I could do:
public interface ClientRepo<T> extends Repo<T>{
}
Addendum: Perhaps I should make my intent for having specific Repos (e.g. ClientRepo) more clear. There is another interface called RepoFactory that returns appropriate Repo to the client, e.g.:
public interface RepoFactory{
ClientRepo createClientRepo();
CustomerRepo createCustomerRepo();
}
This factory is implemented by implementors which in turn, provide the appropriate implementations of the concrete Repos.
In fact from the above you could say that the interface Repo<T> is not used by the client of the api.
Confusing enough I hope!!! Sorry :(
Generic Classes and SubtypingYou can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.
It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.
An interface can extend other interfaces, just as a class subclass or extend another class. However, whereas a class can extend only one other class, an interface can extend any number of interfaces.
I've found a lot more utility in doing
public interface SomeRepo<T> extends Repo<T>{
}
Than in extending interfaces via
public interface ClientRepo extends Repo<Client>{
}
public interface CustomerRepo extends Repo<Customer>{
}
That said, I've done both in the past, and will likely wind up doing both in the future. If you detect too much duplicate code in the latter solution, I'd do my best to replace it with the former solution.
If you want any practical issues, it seems that compilers have a harder time realizing that `public interface ClientRepo extends Repo' can be compatible with Repo. It doesn't happen too often (but when it does it takes a number of attempts to get the generics interfacing right).
Well it depends if your extending interface/class could be generic, too. In your example I would assume that you want to do
public interface ClientRepo extends Repo<Client>{
}
Because with
public interface ClientRepo<T> extends Repo<T>{
}
You could do things like
ClientRepo<Customer>
which is probably not the desired behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With