尝试使用泛型类型类,但遇到以下问题,即:
类型不匹配:推断的类型是
ChildClass但SuperClass<SuperType>预期
open class SuperClass<T> where T: SuperType {
fun modifySomething(input: T): T {
input.someValue.inc()
return input
}
}
open class SuperType {
val someValue: Int = 0
}
class ChildClass : SuperClass<ChildType>()
class ChildType: SuperType() {
fun getModifiedValue(): Int {
return someValue
}
}
class TestEnvironment {
fun testType(superClass: SuperClass<SuperType>) {
// do something with superClass
}
fun itDoesntWork() {
testType(ChildClass()) // compilation error
}
}
Run Code Online (Sandbox Code Playgroud)
所需的结果是函数 testType(superClass: SuperClass<SuperType>) 应在 不使用通配符的情况下接受类ChildClass() *
由于泛型差异,您的代码无法正常工作。SuperClass被定义为
open class SuperClass<T> where T: SuperType { ... }
Run Code Online (Sandbox Code Playgroud)
并且其类型参数T被声明为不变的(它没有out或in修饰符)。因此,子类型关系如下:
DerivedClass<ChildType>是不是的子类型SuperClass<SuperType>SuperClass<ChildType>是不是的子类型SuperClass<SuperType>DerivedClass<SuperType> 是的子类型SuperClass<SuperType>。由于函数参数应该属于参数类型的子类型,并且ChildClass实际上是DerivedClass<ChildType>,因此您不能将其ChildClass作为传递SuperClass<SuperType>。
您可以通过将out投影添加到参数类型来解决此问题testType:
fun testType(superClass: SuperClass<out SuperType>)
Run Code Online (Sandbox Code Playgroud)
这基本上意味着该函数接受SuperClass<T>where T是的子类型SuperType。当然,它在superClass用法上增加了一些限制:T绝对可以是的任何子类型SuperType,将任何内容传递给期望T作为参数的函数都是不安全的,因此禁止这样做。
另外,请参见另一个答案,该答案解释了不变泛型行为的原因:(链接)
| 归档时间: |
|
| 查看次数: |
1923 次 |
| 最近记录: |