我有以下类型:
class Images<T : Image>(
val images: List<T>,
val totalCount: Int
)
因此,这里的列表只能包含从Image
继承的对象。
现在我有了一个接口:
interface ImageService<T : Image> {
fun getNewImages(offset: Int, limit: Int): Images<T>
fun getNextImage(): Image
}
具体实施:
class NumberImageService : ImageService<NumberImage> {
override fun getNewImages(offset: Int, limit: Int): Images<NumberImage> {
// return something
}
override fun getNextImage(): NumberImage {
// return something
}
}
到目前为止,一切都很好。现在我有了另一个类,我可以根据枚举输入来决定使用哪个具体实现:
class ImageQueryResolver : GraphQLQueryResolver {
fun getNewImages(input: ImageInput, offset: Int, limit: Int = Int.MAX_VALUE): Images {
return when (input.imageType) {
ImageEnum.NUMBER ->
numberImageService.getNewImages(offset, limit)
ImageEnum.LETTER ->
letterImageService.getNewImages(offset, limit)
}
}
fun getNextImage(input: ImageInput): Image {
// return something
}
}
这给了我一个错误,因为getNewImages
的返回类型,也就是Images
,需要有一个参数:
One type argument expected for class Images<T : Image>
但我现在需要使用哪个论点呢?
正如我在评论中提到的,您可以使用Images<out Image>
作为返回类型。这基本上是说实现可以使用Image
或Image
的子类型。如果您熟悉Java,那么它与使用Images<? extends Image>
类似。
由于Images
接口只生成T
类型的对象,因此另一个选项是使用声明站点差异,而不是使用站点差异。换句话说,你可以有:
interface Images<out T : Image> {
// methods...
}
这将允许您使用Images<Image>
作为返回类型:
fun getNewImages(input: ImageInput, offset: Int, limit: Int = Int.MAX_VALUE): Images<Image> {
return when (input.imageType) {
ImageEnum.NUMBER ->
numberImageService.getNewImages(offset, limit)
ImageEnum.LETTER ->
letterImageService.getNewImages(offset, limit)
}
}
以下是Kotlin中关于泛型的参考:https://kotlinlang.org/docs/reference/generics.html
您需要指定该参数,因为Images是通用的。因此,我建议二选一:
1(Images<out Image>
->返回类型是图像的一个子类型
2(Images<*>
->我不在乎是什么通用类型
我认为第一个解决方案更好(我们限制了这个值,这样我们就更了解发生了什么(;(
试试这个:
fun <T : Image> getNewImages(input: ImageInput, offset: Int, limit: Int = Int.MAX_VALUE): Images<T> {
return when (input.imageType) {
ImageEnum.NUMBER ->
numberImageService.getNewImages(offset, limit)
ImageEnum.LETTER ->
letterImageService.getNewImages(offset, limit)
}
}