在接口扩展中指定泛型

时间:2011-03-28 14:37:35

标签: java generics

在使用其他接口扩展接口时,是否应该指定泛型类型的具体类型?

我的意思是,如果我有一个界面:

public interface Repo<T>{
      Collection<T> search(String params);
      T get(String id);
}

然后是一大堆特定的存储库,例如 ClientRepo CustomerRepo 等......指定类型 T 是合理的扩展此界面,例如:

public interface ClientRepo extends Repo<Client>{
}
public interface CustomerRepo extends Repo<Customer>{
}

客户和客户只是某些类。

有没有人有类似的问题?我的意思是我能做到:

public interface ClientRepo<T> extends Repo<T>{
}

附录: 也许我应该让我更清楚地了解具体的Repos(例如ClientRepo)。还有另一个名为 RepoFactory 的接口,它向客户端返回适当的Repo,例如:

public interface RepoFactory{
      ClientRepo createClientRepo();
      CustomerRepo createCustomerRepo();
}

这个工厂由实现者实现,反过来,它提供了具体Repos的适当实现。

事实上,从上面你可以说api的客户端没有使用 Repo&lt; T&gt; 接口。

我希望有足够的困惑!对不起:(

5 个答案:

答案 0 :(得分:3)

这取决于你的扩展接口/类是否也是通用的。在你的例子中,我假设你想做

public interface ClientRepo extends Repo<Client>{
}

因为

public interface ClientRepo<T> extends Repo<T>{
}

你可以做像

这样的事情
ClientRepo<Customer> 

这可能不是理想的行为。

答案 1 :(得分:3)

我发现在做

方面有更多实用性
public interface SomeRepo<T> extends Repo<T>{
}

比通过

扩展接口
public interface ClientRepo extends Repo<Client>{
}
public interface CustomerRepo extends Repo<Customer>{
}

那就是说,我过去都做过这两件事,并且很可能会在未来做到这两件事。如果在后一种解决方案中检测到过多的重复代码,我会尽力用以前的解决方案替换它。

如果您想要任何实际问题,似乎编译器很难意识到“公共接口ClientRepo扩展Repo”可以与Repo兼容。它不会经常发生(但是当它发生时需要多次尝试才能使泛型接口正确)。

答案 2 :(得分:2)

通用接口(以及整体上的泛型)的目的是具有单个通用实现。即,即使您的接口可能有多个实现,它们也应该处理每个有效的参数类。

如果删除后续接口层中的参数,那么首先就会失去创建通用接口的想法。毕竟,你可以这样做:

 public interface Repo {
      Collection search(String params);
      Object get(String id);
 }

 public interface ClientRepo {
      Collection<Client> search(String params);
      Client get(String id);
 }

当然,如果您的外部代码支持任何Repo实现的参数化操作,那么拥有通用接口仍然有用。但您也可以认为这些操作应该是Repo接口的一部分。

总而言之,这是可行的并且不难证明,但对我来说看起来有点尴尬:仅仅通过查看你的例子,很难弄清楚你的意图是什么,这总是警告的标志。

答案 3 :(得分:0)

could正确定义了类型

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
    }
};
获得更严格的类型检查。

答案 4 :(得分:0)

原来我正在寻找的解决方案只是抛弃我所有的专用接口:

public interface RepoFactory{
    Repo<Client> createClientRepo();
    Repo<Customer> createCustomerRepo(); }

这样我就可以保持静态类型检查以强制执行api,并为我的Factory的实现获得额外的灵活性。