Kotlin:覆盖子类型内的通用属性 [英] Kotlin: override generic property within subtype
问题描述
我试图编写一些泛型代码,但无法删除PROPERTY类型不是重写属性
的子类型错误。
我的代码的简化版本:
抽象类BaseP< V> ; {
var view:V? = null
}
抽象类BaseF {
fun smth(){
pp.view = this
}
抽象val pp: BaseP< BaseF>
}
抽象类SubF:BaseF(){$ b $ b抽象覆盖val pp:BaseP< SubF>
//错误:(20,30)'pp'的类型不是重写属性的子类型'public abstract val pp:BaseP< BaseF>在BaseF中定义'
}
我发现错误可能是 @Suppress
-ed,但我怀疑这是最好的和唯一的方法。有什么更好的?
毕竟我不明白,为什么 subtypeA< subtypeB>
不计数为 baseA< baseB>
的子类型,有人可以解释这个吗? 首先, SubtypeA
是 BaseA
的子类型,所以问题出在泛型参数子类型。
答案在于 Kotlin泛型差异,类似于 Java的。为什么不把 SubtypeA< SubtypeB>
计为 BaseA< BaseB>
?
默认情况下,泛型不变,这意味着即使更简单情况下,对于一个类 可能有两种情况: 如果你只想从你的类的实例 A 中取 此处 A< T>
, A< SubtypeB> $ c $除非在
和<$中有变量修饰符的指定,否则c <和
(或 Java通配符 A< BaseB>
不是彼此的子类型。 c $ c> out
T
实例,那么您可以使用 out
修饰符: A< out T>
。
A< SubtypeB>
成为 A< BaseB>
的子类型,因为从 A< SubtypeB>
显然可以使用 BaseB
的实例,而不是相反。
A< in T>
。 这里 A< BaseB>
是a因为 A< BaseB>
的每个实例也可以接收 A< code> A< SubtypeB>
SubtypeB ,但反之亦然。 T
到/从您的课程 A< T>
,那么 T
它是不变的,因此 A
和 A
是 A< B>
的子类型:否则会导致与上述矛盾。
案例:在您的 BaseP< B>
中,您都将 V
的项目放入 view
属性,所以 V
只能是不变的,并且 BaseP< SubF>
不是 BaseP< BaseF>
的子类型,也不是 SubP< SubF>
。
I trying to write some generic code, but can't get rid of Type of 'PROPERTY' is not a subtype of the overridden property
error.
Simplified version of my code:
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'
}
I found that error can be @Suppress
-ed, but I doubt it is best and only way. Is there something better?
And after all I can't understand, why subtypeA<subtypeB>
doesn't count as subtype of baseA<baseB>
, can someone explain this?
First, SubtypeA<B>
is a subtype of BaseA<B>
, so the problem is in the generics parameters subtyping.
The answer lies in Kotlin generics variance, which is similar to that of Java.
Why doesn't
SubtypeA<SubtypeB>
count as subtype ofBaseA<BaseB>
?
The generics are invariant by default, which means that, even in simpler case, for a class A<T>
, A<SubtypeB>
and A<BaseB>
are not subtypes of each other unless otherwise is specified by variance modifiers in
and out
(or Java wildcards).
Two cases are possible:
If you want only to take
T
instances out of instances of your classA
, then you can useout
modifier:A<out T>
.Here
A<SubtypeB>
becomes a subtype ofA<BaseB>
, because fromA<SubtypeB>
you can obviously take instances ofBaseB
, and not vice versa.If you want only to pass
T
into your class' methods, then usein
modifier in your class declaration:A<in T>
.And here
A<BaseB>
is a subtype ofA<SubtypeB>
, because every instance ofA<BaseB>
can also receiveSubtypeB
into the methods, but not vice versa.
If you both pass and take T
to/from your class A<T>
, then the only option for T
it is to be invariant, so that neither A<SubB>
nor A<SuperB>
are subtypes of A<B>
: otherwise would lead to a contradiction to the above.
And this is exactly the case: in your BaseP<B>
, you are both taking items of V
and putting ones into view
property, so V
can only be invariant, and BaseP<SubF>
is not a subtype of BaseP<BaseF>
, neither is SubP<SubF>
.
这篇关于Kotlin:覆盖子类型内的通用属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!