Kotlin 扩展函数
Kotlin 使程序员能够向现有类添加更多功能,而无需继承它们。这是通过称为扩展的功能实现的。当一个函数被添加到一个现有的类中时,它被称为扩展函数。要将扩展函数添加到类,请定义一个附加到类名的新函数,如以下示例所示:
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()}")
}
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())
}
Kotlin
// 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())
}
Kotlin
// 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()
}
Kotlin
class MyClass {
// companion object declaration
companion object {
fun display(){
println("Function declared in companion object")
}
}
}
fun main(args: Array) {
// invoking member function
val ob = MyClass.display()
}
Kotlin
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) {
val ob = MyClass.display("Function declared in companion object")
println(ob)
// invoking the extension function
val ob2 = MyClass.abc()
}
输出:
Area of the circle is 19.634954084936208
Perimeter of the circle is 15.707963267948966
解释:
在这里,使用类Circle.perimeter()的点表示法将一个新函数附加到类,它的返回类型是 Double。在 main函数中,创建了一个对象来实例化 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,则返回 -(value),如果参数值大于零,则返回相同的值。
扩展是静态解析的
关于扩展函数需要注意的一点是它们是静态解析的,即执行哪个扩展函数完全取决于调用它的表达式的类型,而不是取决于在运行时最终执行表达式时解析的类型.以下示例将使上述论点清楚:
科特林
// 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的一个实例。根据动态方法 dispatch的概念,输出应该是25 ,但是由于扩展函数是静态解析的,所以在类型 A 上调用操作函数。因此输出是 10。
可空接收器
扩展函数也可以用可以为null的类类型来定义。在这种情况下,当在扩展函数中添加对 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) {
// 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) {
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