科特林扩展功能
Kotlin 让程序员能够通过给现有的类增加更多的功能,而无需继承它们。这是通过一个名为扩展的特性实现的。当一个函数被添加到现有的类中时,它被称为扩展函数。
要向类添加扩展函数,定义一个追加到类名的新函数,如下例所示:
package kotlin1.com.programmingKotlin.chapter1
// A sample class to demonstrate extension functions
class Circle (val radius: Double){
// member function of class
fun area(): Double{
return Math.PI * radius * radius;
}
}
fun main(){
// Extension function created for a class Circle
fun Circle.perimeter(): Double{
return 2*Math.PI*radius;
}
// create object for class Circle
val newCircle = Circle(2.5);
// invoke member function
println("Area of the circle is ${newCircle.area()}")
//invoke extension function
println("Perimeter of the circle is ${newCircle.perimeter()}")
}
输出:
Area of the circle is 19.634954084936208
Perimeter of the circle is 15.707963267948966
解释:
在这里,一个新的函数用点符号追加到类 Circle.perimeter()
中,它的返回类型是 Double。在主函数中,创建一个对象来实例化类 Circle,并在 println()
语句中调用该函数。当成员函数被调用时,它返回圆的面积,类似地,扩展函数返回圆的周长。
使用扩展函数的扩展库类–
Kotlin 不仅允许扩展用户定义的类,还允许扩展库类。扩展函数可以添加到库类中,并以类似于用户定义类的方式使用。
以下示例演示了为用户定义的类创建的扩展函数-
fun main(){
// Extension function defined for Int type
fun Int.abs() : Int{
return if(this < 0) -this else this
}
println((-4).abs())
println(4.abs())
}
输出:
4
4
说明:这里,我们已经使用扩展函数扩展了库函数。我们对整数值执行了模运算。我们已经传递了整数值-4 和 4,并获得了两者的正值。如果参数值小于 0,则返回-(值),如果参数值大于 0,则返回相同的值。
扩展是静态解析的–
关于扩展函数需要注意的一点是它们是静态解析的,即执行哪个扩展函数完全取决于调用它的表达式的类型,而不是运行时表达式最终执行时解析的类型。
下面的例子将使上述论点变得清晰:
// Open class created to be inherited
open class A(val a:Int, val b:Int){
}
// Class B inherits A
class B():A(5, 5){}
fun main(){
// Extension function operate defined for A
fun A.operate():Int{
return a+b
}
// Extension function operate defined for B
fun B.operate():Int{
return a*b;
}
// Function to display static dispatch
fun display(a: A){
print(a.operate())
}
// Calling display function
display(B())
}
输出:
10
说明: 如果你熟悉 Java 或者其他任何面向对象的编程语言,你可能会在上面的程序中注意到,由于B 类继承了A 类,传递给 display 函数的参数是B 类的一个实例。根据动态方法调度的概念,输出应该是 25 ,但是由于扩展函数是静态解析的,所以在类型 a 上调用操作函数,因此输出是 10。
可空接收器–
扩展函数也可以定义为类类型可空。在这种情况下,当在扩展函数中添加对 null 的检查并返回适当的值时。
作为可空接收器的扩展函数示例–
// A sample class to display name name
class AB(val name: String){
override fun toString(): String {
return "Name is $name"
}
}
fun main(){
// An extension function as a nullable receiver
fun AB?.output(){
if(this == null){
println("Null")
}else{
println(this.toString())
}
}
val x = AB("Charchit")
// Extension function called using an instance
x.output()
// Extension function called on null
null.output()
}
输出:
Name is Charchit
Null
伴随对象扩展–
如果一个类包含伴随对象,那么我们也可以为伴随对象定义扩展函数和属性。
伴随对象声明–
class MyClass {
// companion object declaration
companion object {
fun display(){
println("Function declared in companion object")
}
}
}
fun main(args: Array<String>) {
// invoking member function
val ob = MyClass.display()
}
输出:
Function declared in companion object
就像调用伴随对象的常规成员函数一样,只使用类名作为限定符就可以调用扩展函数。 伴随对象扩展示例–
class MyClass {
companion object {
// member function of companion object
fun display(str :String) : String{
return str
}
}
}
// extension function of companion object
fun MyClass.Companion.abc(){
println("Extension function of companion object")
}
fun main(args: Array<String>) {
val ob = MyClass.display("Function declared in companion object")
println(ob)
// invoking the extension function
val ob2 = MyClass.abc()
}
输出:
Function declared in companion object
Extension function of companion object