Kotlin中无需向基类传子类类型即可实现Behavior泛型匹配Node实际类型?
两种可行的实现方案
方案1:运行时类型校验,Node类不带泛型参数
这个方案的核心是通过内联+具体化类型参数,在设置Behavior时做类型校验,不需要Node基类声明泛型,继承更简洁:
// Behavior类保持你预期的写法 open class Behavior<NodeType: Node> { open fun attach(node: NodeType) {} } class SubBehavior : Behavior<SubNode>() { override fun attach(node: SubNode) { println("成功绑定到SubNode") } } open class Node { private var behavior: Behavior<*>? = null inline fun <reified T : Node> setBehavior(behavior: Behavior<T>) { @Suppress("UNCHECKED_CAST") if (this is T) { this.behavior = behavior behavior.attach(this) } else { throw IllegalArgumentException( "Behavior需要绑定到${T::class.simpleName}类型节点,实际节点类型为${this::class.simpleName}" ) } } } open class SubNode : Node()
使用示例:
fun main() { val subNode = SubNode() subNode.setBehavior(SubBehavior()) // 正常执行 val commonNode = Node() commonNode.setBehavior(SubBehavior()) // 运行时抛出参数异常,符合预期 }
优缺点:节点继承时不需要传递自身类型,写法更简洁,但是类型不匹配的问题只能在运行时发现,适合你能保证节点和Behavior类型匹配的场景。
方案2:优化递归泛型写法
你原本使用的「子类传递自身类型给基类」的方案是JVM语言里实现编译期自类型匹配的标准方案,实际生产中普及度很高,书写成本很低,还可以通过泛型传递适配多层继承场景:
open class Node<SubType : Node<SubType>> { var behavior: Behavior<SubType>? = null set(value) { field = value value?.attach(this as SubType) } } // 单层继承写法 class SubNode : Node<SubNode>() // 多层继承写法 open class MiddleNode<SubType: MiddleNode<SubType>> : Node<SubType>() class ChildNode : MiddleNode<ChildNode>()
优缺点:全程编译期类型安全,不会出现运行时类型错误,仅在继承时多写一个泛型参数,开发成本很低,适合对类型安全要求高的生产场景。
内容的提问来源于stack exchange,提问作者manabreak
相关产品推荐
相关产品推荐

