gpt4 book ai didi

java - 为什么 java Iterable 接口(interface)不能采用泛型通配符?或者 : why can't I an overriding iterator() method return an Iterator for a subclass?

转载 作者:搜寻专家 更新时间:2023-11-01 01:28:14 25 4
gpt4 key购买 nike

我有一些类:SearchResponse、SearchResponseHit、SpecialSearchResponse(扩展 SearchResponse)和 SpecialSearchResponseHit(扩展 SearchResponseHit)。

SearchResponse 看起来像这样:

public class SearchResponse implements Iterable<SearchResponseHit> {

[...]

public Iterator<SearchResponseHit> iterator() {
return searchResponseHits.iterator();
}
}

这使我可以在 foreach 循环中使用 SearchResponse 的实例,如下所示:

for (SearchResponseHit hit : mySearchResponse) {
[...]
}

现在,我想做的是在我有一个 SpecialSearchResponse 的实例时编译这段代码,但不知道如何做:

for (SpecialSearchResponseHit specialHit : mySpecialSearchResponse) {
[...]
}

这给了我以下编译器错误:

Type mismatch: cannot convert from element type SearchResponseHit to SpecialSearchResponseHit

如果我尝试将此代码添加到 SpecialSearchResponse:

public Iterator<SpecialSearchResponseHit> iterator() {
[...]
}

...我收到错误:

The return type is incompatible with Iterable<SearchResponseHit>.iterator()

我尝试将 SearchResponse 中的方法更改为:

    public Iterator<? extends SearchResponseHit> iterator() {
return searchResponseHits.iterator();
}

...但这给了我错误:

The return type is incompatible with Iterable<SearchResponseHit>.iterator()

然后我尝试将类定义更改为:

public class SearchResponse implements Iterable<? extends SearchResponseHit>

...但这给了我这个错误:

    The type SearchResponse cannot extend or implement Iterable<? extends SearchResponseHit>. A supertype may not specify any wildcard

解决这个问题的最好(和最漂亮)的方法是什么?还是我必须跳过 foreach 方法(以及其他在幕后使用 Iterable 接口(interface)的函数)并编写一个 getSpecialIterator() 方法然后直接使用迭代器?

问候/J

最佳答案

一种方法是按以下方式声明各种类:

public class SearchResponse<T  extends SearchResponseHit> implements Iterable<T> {
List<T> searchResponseHits;

public Iterator<T> iterator() {
return searchResponseHits.iterator();
}
}

public class SearchResponseHit {}

public class SpecialSearchResponse extends SearchResponse<SpecialSearchResponseHit> {}
public class SpecialSearchResponseHit extends SearchResponseHit {}

这样你就可以这样称呼他们:

    SearchResponse<SearchResponseHit> sr = new SearchResponse<SearchResponseHit>();
for (SearchResponseHit h : sr) {}

SpecialSearchResponse ssr = new SpecialSearchResponse();
for (SpecialSearchResponseHit h : ssr) {}

但这在 SearchResponse 类中引入了泛型,您不能再简单地声明 SearchResponse sr = new SearchResponse()(没有警告和转换)。


更新
根据您的评论,您可以选择创建一个包含泛型样板的通用父类(super class) - 您可以将其抽象化并封装为私有(private),这样您的类的用户就看不到它:

abstract class AbstractSearchResponse<T  extends SearchResponseHit> implements Iterable<T>{
List<T> searchResponseHits;

public Iterator<T> iterator() {
return searchResponseHits.iterator();
}
}

public class SearchResponse extends AbstractSearchResponse<SearchResponseHit> { }
public class SpecialSearchResponse extends AbstractSearchResponse<SpecialSearchResponseHit> {}

现在您可以随心所欲地调用 2 个 child :

SearchResponse sr = new SearchResponse();
for (SearchResponseHit h : sr) {}

SpecialSearchResponse ssr = new SpecialSearchResponse();
for (SpecialSearchResponseHit h : ssr) {}

关于java - 为什么 java Iterable 接口(interface)不能采用泛型通配符?或者 : why can't I an overriding iterator() method return an Iterator for a subclass?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10934103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com