在Kotlin中,关键字super用于调用超类或实现的接口中的方法或属性实现。与Java不同,Kotlin允许明确指定通过哪个接口或类调用方法实现,这在多个具有相同方法的接口之间出现"冲突"时尤其重要。
特点: 如果一个类实现了多个接口,其中定义了具有相同签名的方法,并且有默认实现,则必须明确指定使用哪种实现。
示例:
interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // 明确调用A.foo super<B>.foo() // 明确调用B.foo } }
这一点在Java中不直接支持(Java在Java 8之前不允许接口有字段/方法实现,即使在Java 8中,机制也不同)。
"在Kotlin中可以通过多级继承访问超类方法的实现吗?"
super<Intermediate>.foo(),但并非如此——只能访问直接超类或实现该方法的接口。示例:
open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // 将调用Mid.foo() // super<Base>.foo() — 编译错误 } }
故事
在一个大型项目中,接口
Logger和Auditor都定义了方法record()。在实现同时继承这两个接口的类时,程序员没有明确重写record(),最终导致编译错误"Class must override public open fun record()"。不得不手动实现该方法,并明确委托给相应的接口。
故事
尝试通过多个中间层调用超类中实现的方法(例如,
super<Base>.foo())时,编译出现错误。开发者不了解Kotlin的限制,无法理解为什么直接调用是不可能的。
故事
在API更新后,其中一个接口添加了与另一个接口相同的默认方法实现。旧代码由于实现冲突而无法再编译——不得不明确解决冲突,自己实现方法并选择在内部调用哪些超接口的实现。