如何为Kotlin扩展函数实现多态行为?
Kotlin扩展函数实现多态行为的解决方案
Kotlin扩展函数是静态绑定的——编译时会根据变量的声明类型决定调用哪个扩展,而非运行时的实际类型。这就是为什么用Parent类型引用调用GrandChild1Class实例的foo时,会执行Parent的扩展函数。由于原Java类层级无法修改,没法通过添加虚函数实现原生多态,我们可以用以下几种方式模拟动态分发:
方案1:在Parent扩展函数中直接做类型分发
把分发逻辑写在Parent的foo扩展里,运行时判断实际类型,调用对应逻辑:
// Parent接口的扩展函数,负责分发 fun Parent.foo() { when (this) { is GrandChild1Class -> this.foo() // 调用GrandChild1的专属扩展 else -> { // Parent默认逻辑 println("Parent's foo") } } } // GrandChild1Class的专属扩展函数 fun GrandChild1Class.foo() { println("GrandChild1Class's foo") }
调用示例:
val parent: Parent = GrandChild1Class() parent.foo() // 会执行GrandChild1Class的foo逻辑
方案2:用工具类集中处理分发
如果扩展逻辑复杂,把分发逻辑抽成单独的工具类,让代码更清晰:
object FooDispatcher { fun handleFoo(parent: Parent) { when (parent) { is GrandChild1Class -> parent.foo() is Child1Class -> println("Child1Class's foo") is Child2Class -> println("Child2Class's foo") else -> println("Parent's foo") } } } // 各类型的扩展函数 fun GrandChild1Class.foo() = println("GrandChild1Class's foo") fun Parent.foo() = FooDispatcher.handleFoo(this)
调用方式不变,parent.foo()会自动根据实际类型分发到对应逻辑。
方案3:用包装类实现类级多态
创建密封包装类,利用Kotlin类的多态特性来实现动态调用:
sealed class ParentWrapper(val original: Parent) { open fun foo() = println("Parent's foo") } class GrandChild1Wrapper(child: GrandChild1Class) : ParentWrapper(child) { override fun foo() = println("GrandChild1Class's foo") } class Child1Wrapper(child: Child1Class) : ParentWrapper(child) { override fun foo() = println("Child1Class's foo") } class Child2Wrapper(child: Child2Class) : ParentWrapper(child) { override fun foo() = println("Child2Class's foo") } // 扩展函数快速包装原对象 fun Parent.wrap(): ParentWrapper = when (this) { is GrandChild1Class -> GrandChild1Wrapper(this) is Child1Class -> Child1Wrapper(this) is Child2Class -> Child2Wrapper(this) else -> ParentWrapper(this) }
调用示例:
val parent: Parent = GrandChild1Class() parent.wrap().foo() // 执行GrandChild1的专属逻辑
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

