面试题答案
一键面试- 优先级规则:
- 当Kotlin类的成员函数与扩展函数具有相同的签名时,成员函数具有更高的优先级。也就是说,如果类中定义了一个与扩展函数签名相同的成员函数,调用该函数时会优先调用成员函数。这是因为成员函数是类定义的一部分,与类的紧密程度更高,而扩展函数本质上是一种通过静态方法实现的对类的“外部扩展”。
- 调用扩展函数而非成员函数的方法:
- 可以通过将对象转换为其超类型(如果超类型没有同名的成员函数),然后调用扩展函数。例如,如果有一个类
SubClass
继承自SuperClass
,SubClass
有一个成员函数func
,SuperClass
有一个针对SuperClass
的扩展函数func
,那么将SubClass
对象转换为SuperClass
类型后调用func
,就会调用到扩展函数。
- 可以通过将对象转换为其超类型(如果超类型没有同名的成员函数),然后调用扩展函数。例如,如果有一个类
- 复杂示例:
open class Animal {
open fun makeSound() {
println("Animal makes a sound")
}
}
class Dog : Animal() {
override fun makeSound() {
println("Dog barks")
}
fun makeSound(sound: String) {
println("Dog makes sound: $sound")
}
}
fun Animal.makeSound(sound: String) {
println("Animal makes sound: $sound")
}
fun main() {
val dog = Dog()
dog.makeSound() // 调用Dog类的成员函数makeSound(),输出 "Dog barks"
dog.makeSound("woof woof") // 调用Dog类的成员函数makeSound(String),输出 "Dog makes sound: woof woof"
(dog as Animal).makeSound("generic sound") // 将Dog对象转换为Animal类型后调用扩展函数makeSound(String),输出 "Animal makes sound: generic sound"
}
在上述示例中:
- 首先定义了
Animal
类及其makeSound
成员函数。 Dog
类继承自Animal
,重写了makeSound
成员函数,并新增了一个带参数的makeSound
成员函数。- 同时定义了针对
Animal
类的扩展函数makeSound(String)
。 - 在
main
函数中,直接调用dog.makeSound()
调用的是Dog
类重写的成员函数;调用dog.makeSound("woof woof")
调用的是Dog
类带参数的成员函数;而将dog
转换为Animal
类型后调用makeSound("generic sound")
,调用的是扩展函数。