提问人:Brick 提问时间:11/17/2023 最后编辑:Brick 更新时间:11/17/2023 访问量:53
为什么“out”不允许通用 Kotlin 接口专门用于子类?
Why doesn't `out` allow a generic Kotlin interface to be specialized in child classes?
问:
我在一个新的 Kotlin 代码主体中有以下两个类:
open class Parent {
open fun f(a : Double) : Parent {
TODO("Implement")
}
}
class Child : Parent() {
override fun f(a : Double) : Child {
TODO("Implement")
}
}
在这种情况下,子类在法律上覆盖了父类的实现。参数类型相同,并且允许返回类型是父级中给定的返回类型的子级。目前为止,一切都好。f
我还有一个现有的代码库,它有一个接口,以及该接口的许多实现,这些实现具有这种模式:
interface F<out T> {
fun f(a : Double) : T
}
class Uncle : F<Uncle> {
override fun f(a : Double) : Uncle {
TODO("Implement")
}
}
我想通过拥有和实现接口使新代码与现有代码库一起工作,但我被卡住了。如果我这样做对父级来说很好,但是我不允许这样做,因为现在根据编译器对接口的参数值不一致。如果我为 创建并且没有明确指定接口,那么在某些情况下,子类的行为与预期的行为并不完全相同,因为这不会捕获子类实例的返回类型的“相同性”。Parent
Child
F
Parent : F<Parent>
Child : Parent(), F<Child>
Child
F
Parent : F<Parent>
Child : Parent()
f
对于一对常规的类和不带参数的接口,此问题是意料之中的,并且最终与类型擦除有关。(请参阅 Kotlin 中两次从同一泛型接口继承(使用不同类型)的任何方法?和两次实现泛型接口(使用不同类型)的 Kotlin 类。out
不过,我的情况更具体。如果允许,由于使用了 .(请参 阅 kotlin 中的 What is out 关键字 。我不认为类型擦除论点适用于这种情况。F<Child>
F<Parent>
out
所以两个相关的问题:
- 是否有根本原因无法支持这一点(例如一般情况下的类型擦除参数)?
- 有没有好的解决方法?
答: 暂无答案
评论