java 在接口扩展中指定泛型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5460569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specify Generics in interface extends
提问by Andriy Drozdyuk
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 Twhen extending this interface, e.g.:
然后是一大堆特定的存储库,如ClientRepo,CustomerRepo等......在扩展此接口时指定类型T是否合理,例如:
public interface ClientRepo extends Repo<Client>{
}
public interface CustomerRepo extends Repo<Customer>{
}
where Client and Customer are just some classes.
其中 Client 和 Customer 只是一些类。
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 RepoFactorythat returns appropriate Repo to the client, e.g.:
附录:也许我应该让我的意图更明确地拥有特定的 Repos(例如 ClientRepo)。还有另一个名为RepoFactory 的接口,它向客户端返回适当的 Repo,例如:
public interface RepoFactory{
ClientRepo createClientRepo();
CustomerRepo createCustomerRepo();
}
This factory is implemented by implementorswhich in turn, provide the appropriate implementations of the concrete Repos.
该工厂由实现者实现,而实现者又提供具体 Repos 的适当实现。
In fact from the above you could say that the interface Repo<T>is not used by the client of the api.
事实上,从上面你可以说接口Repo<T>没有被 api 的客户端使用。
Confusing enough I hope!!! Sorry :(
我希望足够混乱!!!对不起 :(
采纳答案by Andriy Drozdyuk
Turns out the solution I was looking for was simply to throw out all my specialized interfaces:
原来我正在寻找的解决方案只是扔掉我所有的专用接口:
public interface RepoFactory{
Repo<Client> createClientRepo();
Repo<Customer> createCustomerRepo(); }
This way I get to both keep my static type-checking to enforce the api and also gain an additional flexibility for implementations of my Factory.
通过这种方式,我既可以保持静态类型检查以强制执行 api,也可以为我的工厂的实现获得额外的灵活性。
回答by Daff
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.
这可能不是所需的行为。
回答by Edwin Buck
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).
如果您想要任何实际问题,似乎编译器很难意识到`public interface ClientRepo extends Repo' 可以与 Repo 兼容。它不会经常发生(但是当它发生时,需要多次尝试才能正确连接泛型)。
回答by biziclop
The purpose of generic interfaces (and generics on the whole) is to have a single generic implementation. I.e, even though your interface might have multiple implementations, they should all handle every valid parameter class.
泛型接口(以及整个泛型)的目的是拥有一个单一的泛型实现。即,即使您的接口可能有多个实现,它们都应该处理每个有效的参数类。
If you remove the parameter in a subsequent layer of interfaces, it kind of defeats the idea of having a generic interface in the first place. After all, you could simply do:
如果您在后续的接口层中删除参数,它首先会破坏具有通用接口的想法。毕竟,您可以简单地执行以下操作:
public interface Repo {
Collection search(String params);
Object get(String id);
}
public interface ClientRepo {
Collection<Client> search(String params);
Client get(String id);
}
Of course if you have external code that supports parametrised operations on any Repo
implementation, having a generic interface could still be useful. But you can also argue that these operations should be part of the Repo
interface.
当然,如果您有支持对任何Repo
实现进行参数化操作的外部代码,拥有通用接口仍然很有用。但是您也可以争辩说这些操作应该是Repo
接口的一部分。
All in all, it's workable and isn't hard to justify but it looks a bit awkward to me: just by looking at your example, it's difficult to figure out what your intent is, which is always a sign of warning.
总而言之,这是可行的并且不难证明,但对我来说看起来有点尴尬:仅通过查看您的示例,很难弄清楚您的意图是什么,这总是一个警告标志。
回答by CMR
You coulddefine types properly
您可以正确定义类型
interface BaseType { }
interface Client extends BaseType {}
然后,你可以定义
interface Repo<T extends BaseType> {
Collection<T> search(String params);
T get(String id);
}
interface ClientRepo extends Repo<Client> { }
并随着实施
ClientRepo c = new ClientRepo() {
@Override
public Collection<Client> search(String params) {// implementation here
}
@Override
public Client get(String id) {// implementation here
}
};
获得更严格的类型检查。