Kotlin泛型使用问题:期望父类型而非子类的解决方案咨询
泛型接口重构的正确实现方案
核心问题分析
你的代码存在三个关键问题:
- 泛型参数逻辑错位:排序接口的泛型应该指向要处理的数据类型而非仓库类型,当前设计把仓库作为泛型参数,导致类型匹配完全混乱。
- 成员方法调用错误:伪代码里直接用类名调用成员方法
calcSort,不符合Kotlin语法,必须实例化类后调用。 - 最小复现代码的类型不匹配:
SortConcrete的calcSort要求TestRepository<SimpleRepository>,但你传入的是repo.findAll()返回的Array<CustomDataType>,类型完全不兼容。
修正后的实现方案
1. 重新梳理泛型结构
让排序接口的泛型对应要处理的数据类型,仓库接口的泛型也对应存储的数据类型,实现类与特定数据类型绑定:
// 排序接口:泛型T是要处理的数据类型 interface SortInterface<T> { fun calcSort(repo: TestRepository<T>): String } // 仓库接口:泛型T是存储的数据类型 interface TestRepository<T> { fun findAll(): Array<T> } // 具体仓库:存储CustomDataType类型的数据 class SimpleRepository : TestRepository<CustomDataType> { private val list = arrayOf(CustomDataType(), CustomDataType(2, "Second")) override fun findAll(): Array<CustomDataType> = list } // 具体排序实现:针对CustomDataType类型的数据 class CustomDataTypeSort : SortInterface<CustomDataType> { override fun calcSort(repo: TestRepository<CustomDataType>): String { val dataList = repo.findAll() // 这里写针对CustomDataType的排序逻辑,比如按num排序 val sorted = dataList.sortedBy { it.num } println("排序完成:$sorted") return "排序结果已生成" } } data class CustomDataType(var num: Int = 1, var word: String = "STRING")
2. 正确调用方式
fun main() { val repo = SimpleRepository() // 实例化具体排序实现类 val sorter = CustomDataTypeSort() // 传入仓库实例,类型完全匹配 val result = sorter.calcSort(repo) println(result) }
关于Kotlin泛型协变/逆变的补充说明
如果需要让排序接口的实现类兼容父类型数据,可以使用out(协变)或in(逆变):
- 当接口只返回泛型类型数据时,用
out T(比如只读仓库):interface ReadOnlyRepository<out T> { fun findAll(): Array<T> } - 当接口只接收泛型类型数据时,用
in T(比如只写操作的接口):interface WriteOnlyRepository<in T> { fun save(data: T) }
你的场景里,排序接口既接收仓库又返回结果,不需要额外的协变逆变修饰,保持基础泛型即可。
伪代码的修正版本
针对你最初的伪代码,修正后的正确写法:
interface CustomInterface<T> { fun calcSort(repo: CustomDataTypeRepository<T>, word: String): String } // 仓库接口 interface CustomDataTypeRepository<T> { fun getList(): List<T> } // 具体实现类:针对CustomDataType1 class FunctionConcrete1 : CustomInterface<CustomDataType1> { override fun calcSort(repo: CustomDataTypeRepository<CustomDataType1>, word: String): String { val dataList = repo.getList() // 执行CustomDataType1的排序逻辑 return "排序后的结果" } } // 具体数据类 data class CustomDataType1(val id: Int, val name: String) fun calcSortAllInformation() { val customDataRepo: CustomDataTypeRepository<CustomDataType1> = object : CustomDataTypeRepository<CustomDataType1> { override fun getList(): List<CustomDataType1> { return listOf(CustomDataType1(1, "A"), CustomDataType1(2, "B")) } } // 实例化实现类后调用成员方法 val sorter = FunctionConcrete1() val sortString = sorter.calcSort(customDataRepo, "关键词") println(sortString) }
内容的提问来源于stack exchange,提问作者BoydyBoydy
相关产品推荐
相关产品推荐

