You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin泛型类层次编译报错:StrEdge不符合Edge<String, StrEdge>边界

问题原因

StrEdge继承自WeightedEdgeImpl<String>,而WeightedEdgeImpl<String>实现的是WeightedEdge<String, WeightedEdgeImpl<String>>,对应Edge<String, WeightedEdgeImpl<String>>。但Graph<N, E>要求E必须是Edge<N, E>,也就是对于StrGraph来说,E需要满足Edge<String, StrEdge>。当前StrEdge并没有直接实现Edge<String, StrEdge>,而是间接实现了Edge<String, WeightedEdgeImpl<String>>,因此编译器判定类型参数不满足约束。

解决方案

方案一:调整WeightedEdgeImpl的泛型定义,支持子类自引用

修改WeightedEdgeImpl为带自引用泛型的类,让子类可以将自身作为泛型参数传入,从而满足Edge的约束:

interface Edge<N:Any, E:Edge<N,E>> {
    val from: N
    val to: N
    fun copy(f: N = from, t: N = to): E
}

interface WeightedEdge<N:Any,E: WeightedEdge<N, E>> : Edge<N, E> {
    val weight: Int
}

// 修改WeightedEdgeImpl,添加自引用泛型E
open class WeightedEdgeImpl<N:Any, E: WeightedEdgeImpl<N, E>>(
    override val from: N,
    override val to: N,
    override val weight: Int
) : WeightedEdge<N, E> {
    // 让子类实现copy方法
    abstract override fun copy(f: N, t: N): E
}

class StrEdge(from: String, to: String, weight: Int) : WeightedEdgeImpl<String, StrEdge>(from, to, weight) {
    override fun copy(f: String, t: String): StrEdge {
        return StrEdge(f, t, weight)
    }
}

interface Graph<N:Any, E: Edge<N,E>> {

}

class StrGraph : Graph<String, StrEdge> {

}

方案二:让StrEdge直接实现目标接口并委托给WeightedEdgeImpl

通过委托模式复用WeightedEdgeImpl的实现,同时让StrEdge直接实现WeightedEdge<String, StrEdge>,满足Graph的约束:

interface Edge<N:Any, E:Edge<N,E>> {
    val from: N
    val to: N
    fun copy(f: N = from, t: N = to): E
}

interface WeightedEdge<N:Any,E: WeightedEdge<N, E>> : Edge<N, E> {
    val weight: Int
}

open class WeightedEdgeImpl<N:Any>(
    override val from: N,
    override val to: N,
    override val weight: Int
) : WeightedEdge<N,WeightedEdgeImpl<N>> {
    override fun copy(f: N, t: N): WeightedEdgeImpl<N> {
        return WeightedEdgeImpl(f, t, weight)
    }
}

// 直接实现WeightedEdge<String, StrEdge>,并委托给WeightedEdgeImpl
class StrEdge(
    private val delegate: WeightedEdgeImpl<String>
) : WeightedEdge<String, StrEdge> by delegate {
    // 提供构造函数兼容原用法
    constructor(from: String, to: String, weight: Int) : this(WeightedEdgeImpl(from, to, weight))

    override fun copy(f: String, t: String): StrEdge {
        return StrEdge(f, t, delegate.weight)
    }
}

interface Graph<N:Any, E: Edge<N,E>> {

}

class StrGraph : Graph<String, StrEdge> {

}

两种方案都能解决编译错误,方案一更贴近原有的继承结构,方案二通过委托避免了修改父类的泛型定义,适合不想改动原有WeightedEdgeImpl的场景。

内容的提问来源于stack exchange,提问作者ModdyFire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:08:24