Kotlin:覆盖子类型中的泛型 属性
Kotlin: override generic property within subtype
我试图编写一些通用代码,但无法摆脱 Type of 'PROPERTY' is not a subtype of the overridden property
错误。
我的代码的简化版本:
abstract class BaseP<V> {
var view: V? = null
}
abstract class BaseF {
fun smth() {
pp.view = this
}
abstract val pp: BaseP<BaseF>
}
abstract class SubF: BaseF() {
abstract override val pp: BaseP<SubF>
// Error:(20, 30) Type of 'pp' is not a subtype of the overridden property 'public abstract val pp: BaseP<BaseF> defined in BaseF'
}
我发现可以 @Suppress
编辑错误,但我怀疑这是最好且唯一的方法。还有更好的吗?
毕竟我无法理解,为什么 subtypeA<subtypeB>
不算作 baseA<baseB>
的子类型,有人可以解释一下吗?
首先,SubtypeA<B>
是 BaseA<B>
的子类型,所以问题出在泛型参数子类型上。
答案就在Kotlin generics variance, which is similar to that of Java.
Why doesn't SubtypeA<SubtypeB>
count as subtype of BaseA<BaseB>
?
泛型默认是不变的,这意味着,即使在更简单的情况下,对于 class A<T>
,A<SubtypeB>
和 A<BaseB>
也不是每个的子类型other 除非由方差修饰符 in
和 out
(或 Java wildcards)另有规定。
可能有两种情况:
如果您只想从 class A
的实例中 获取 T
个实例,那么您可以使用 out
修饰符:A<out T>
.
此处 A<SubtypeB>
成为 A<BaseB>
的子类型,因为从 A<SubtypeB>
显然可以获取 BaseB
的实例,反之亦然。
如果您只想将 传递 T
到您的 class' 方法中,则在中使用 in
修饰符您的 class 声明:A<in T>
.
而这里的A<BaseB>
是A<SubtypeB>
的子类型,因为A<BaseB>
的每个实例也可以将SubtypeB
接收到方法中,但反之则不行。
如果你都通过 T
to/from 你的 class A<T>
,那么 T
的唯一选择就是保持不变,所以A<SubB>
和 A<SuperB>
都不是 A<B>
的子类型:否则会导致与上述矛盾。
情况确实如此:在你的 BaseP<B>
中,你同时获取了 V
的项目并将其中的项目放入 view
属性,所以 V
只能是不变的,并且 BaseP<SubF>
不是 BaseP<BaseF>
的子类型,也不是 SubP<SubF>
.
我试图编写一些通用代码,但无法摆脱 Type of 'PROPERTY' is not a subtype of the overridden property
错误。
我的代码的简化版本:
abstract class BaseP<V> {
var view: V? = null
}
abstract class BaseF {
fun smth() {
pp.view = this
}
abstract val pp: BaseP<BaseF>
}
abstract class SubF: BaseF() {
abstract override val pp: BaseP<SubF>
// Error:(20, 30) Type of 'pp' is not a subtype of the overridden property 'public abstract val pp: BaseP<BaseF> defined in BaseF'
}
我发现可以 @Suppress
编辑错误,但我怀疑这是最好且唯一的方法。还有更好的吗?
毕竟我无法理解,为什么 subtypeA<subtypeB>
不算作 baseA<baseB>
的子类型,有人可以解释一下吗?
首先,SubtypeA<B>
是 BaseA<B>
的子类型,所以问题出在泛型参数子类型上。
答案就在Kotlin generics variance, which is similar to that of Java.
Why doesn't
SubtypeA<SubtypeB>
count as subtype ofBaseA<BaseB>
?
泛型默认是不变的,这意味着,即使在更简单的情况下,对于 class A<T>
,A<SubtypeB>
和 A<BaseB>
也不是每个的子类型other 除非由方差修饰符 in
和 out
(或 Java wildcards)另有规定。
可能有两种情况:
如果您只想从 class
A
的实例中 获取T
个实例,那么您可以使用out
修饰符:A<out T>
.此处
A<SubtypeB>
成为A<BaseB>
的子类型,因为从A<SubtypeB>
显然可以获取BaseB
的实例,反之亦然。如果您只想将 传递
T
到您的 class' 方法中,则在中使用in
修饰符您的 class 声明:A<in T>
.而这里的
A<BaseB>
是A<SubtypeB>
的子类型,因为A<BaseB>
的每个实例也可以将SubtypeB
接收到方法中,但反之则不行。
如果你都通过 T
to/from 你的 class A<T>
,那么 T
的唯一选择就是保持不变,所以A<SubB>
和 A<SuperB>
都不是 A<B>
的子类型:否则会导致与上述矛盾。
情况确实如此:在你的 BaseP<B>
中,你同时获取了 V
的项目并将其中的项目放入 view
属性,所以 V
只能是不变的,并且 BaseP<SubF>
不是 BaseP<BaseF>
的子类型,也不是 SubP<SubF>
.