Kotlin中的扩展函数(静态分派)

扩展函数

  • 扩展函数可以在已有类中添加新的方法,不会对原类做修改

举例1

  • 对Context进行扩展showToast方法,可以在Fragment、Activity、Application中弹出Toast,showToast的定义可以写在任何文件中
//扩展函数可以定义在任意文件中 fun Context.showToast(msg: String) {     Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() } 
  • 调用showToast
class App : Application() {     override fun onCreate() {         super.onCreate()         showToast("123")     } } 

举例2

  • DensityEx.kt
package com.zhangyu.myapplication  import android.content.Context import android.content.res.Resources import android.util.TypedValue  fun Float.toPx(): Float {     return TypedValue.applyDimension(         TypedValue.COMPLEX_UNIT_DIP,         this,         Resources.getSystem().displayMetrics     ) }  fun Int.toPx():Int{     return toFloat().toPx().toInt() }  fun Context.screenWidth(): Int {     return resources.displayMetrics.widthPixels }  fun Context.screenHeight(): Int {     return resources.displayMetrics.heightPixels }  
  • 调用
class MainActivity : AppCompatActivity() {     override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)         Log.d(TAG, "onCreate: screenWidth=${screenWidth()}")         Log.d(TAG, "onCreate: screenHeight=${screenHeight()}")         Log.d(TAG, "onCreate: ${30.toPx()}")     } } 
 D/MainActivity: onCreate: screenWidth=1080  D/MainActivity: onCreate: screenHeight=2210  D/MainActivity: onCreate: 82 

扩展函数是静态解析的

  • 扩展函数是静态解析的,并不是接收者类型的虚拟成员,在调用扩展函数时,具体被调用的的是哪一个函数,由调用函数的的对象表达式来决定的,而不是动态的类型决定的。
open class C  class D: C()  fun C.foo() = "c"   // 扩展函数 foo  fun D.foo() = "d"   // 扩展函数 foo  fun printFoo(c: C) {     println(c.foo())  // 类型是 C 类 }  fun main(arg:Array<String>){     printFoo(D()) // c } 
  • 若扩展函数和成员函数一致,则使用该函数时,会优先使用成员函数。
class C {     fun foo() { println("成员函数") } }  fun C.foo() { println("扩展函数") }  fun main(arg:Array<String>){     var c = C()     c.foo() //成员函数 } 

参考资料