Generics Kotlin:重写子类型内的泛型属性

Generics Kotlin:重写子类型内的泛型属性,generics,overriding,kotlin,Generics,Overriding,Kotlin,我试图编写一些通用代码,但无法摆脱类型的“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: Bas

我试图编写一些通用代码,但无法摆脱
类型的“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'
}
抽象类BaseP{
变量视图:V?=null
}
抽象类BaseF{
乐趣{
pp.view=这个
}
摘要val-pp:BaseP
}
抽象类SubF:BaseF(){
抽象覆盖val-pp:BaseP
//错误:(20,30)“pp”的类型不是重写属性“public abstract val pp:BaseP在BaseF中定义”的子类型
}
我发现错误可以被抑制,但我怀疑这是最好也是唯一的方法。有更好的吗

毕竟我不明白,为什么
subtya
不算作
baseA
的子类型,有人能解释一下吗?

首先,
subtya
baseA
的子类型,所以问题在于泛型参数子类型

答案在于,这与

为什么
subtya
不算作
BaseA
的子类型

泛型在默认情况下是不变的,这意味着,即使在更简单的情况下,对于类
a
a
a
也不是彼此的子类型,除非方差修饰符
in
out
(或)另有规定

可能有两种情况:

  • 如果只想从类
    A
    的实例中提取
    T
    实例,则可以使用
    out
    修饰符:
    A

    在这里,
    A
    成为
    A
    的一个子类型,因为从
    A
    中显然可以引用
    BaseB
    ,反之亦然

  • 如果您只想将
    T
    传递到类的方法中,那么在类声明中使用
    in
    修饰符:
    A

    这里
    A
    A
    的一个子类型,因为
    A
    的每个实例也可以将
    子类型b
    接收到方法中,但反之亦然

如果你通过并从你的类
A
中取
T
,那么
T
的唯一选择就是保持不变,这样
A
A
都不是
A
的子类型:否则会导致上述矛盾


事实就是这样:在您的
BaseP
中,您都将
V
的项放入
view
属性,因此
V
只能是不变的,
BaseP
不是
BaseP
的子类型,
SubP
也不是哪一行抛出错误?