Kotlin(1.1)學(xué)習(xí)筆記(5)——拓展

擴(kuò)展不能真正的修改他們所擴(kuò)展的類。通過定義一個(gè)擴(kuò)展,你并沒有在一個(gè)類中插入新成員, 僅僅是可以通過該類型的變量用點(diǎn)表達(dá)式去調(diào)用這個(gè)新函數(shù)。
我們想強(qiáng)調(diào)的是擴(kuò)展函數(shù)是靜態(tài)分發(fā)的,即他們不是根據(jù)接收者類型的虛方法。 這意味著調(diào)用的擴(kuò)展函數(shù)是由函數(shù)調(diào)用所在的表達(dá)式的類型來決定的, 而不是由表達(dá)式運(yùn)行時(shí)求值結(jié)果決定的。

官網(wǎng)上描述如果看的不是特別明白,可以參考下面的例子

 open class ExtendTest{
        open fun foo2() = "parent_foo2"
    }
    class ExtendChildTest : ExtendTest(){
        override fun foo2() = "child_foo2"
    }

    fun ExtendTest.foo() = "parent"
    fun ExtendChildTest.foo() = "child"

    /**
     * 拓展是靜態(tài)的。這個(gè)方法下的兩個(gè)顯示,就算調(diào)換位置,效果也是一樣
     */
    fun printFoo(param: ExtendTest) {
        //這里調(diào)用拓展的時(shí)候,所調(diào)用的對(duì)象是由參數(shù)決定定義時(shí)決定,不是運(yùn)行時(shí)由具體的傳參決定
        // 因?yàn)槊鞔_是ExtendTest,不是child類型,
        // 所以message的內(nèi)容是parent,不是child,
        LogUtils.v(TAG,param.foo())//parent

        //下面這個(gè)foo2會(huì)根據(jù)運(yùn)行時(shí)實(shí)際的類型,調(diào)用方法,
        //所以這里是child,不是parent
        LogUtils.v(TAG,param.foo2())//child

    }

    fun extendTest(){
        printFoo(ExtendChildTest())
    }

拓展接收者和拓展分發(fā)者

    open class Extend2 {
        fun a(){}
    }
    open class ExtendTest2{
        fun test(){}

        //Extend是擴(kuò)展接收者,ExtendTest2是擴(kuò)展分發(fā)者
        fun Extend2.b(){
            toString()//接收者優(yōu)先,這個(gè)是Extend.totring
            this@ExtendTest2.toString()
        }
    }

理解了以上的內(nèi)容在看下官網(wǎng)上最后的例子

    open class D {
    }

    class D1 : D() {
    }

    open class C {
        open fun D.foo() {
            println("D.foo in C")
        }

        open fun D1.foo() {
            println("D1.foo in C")
        }

        fun caller(d: D) {
            d.foo()   // 調(diào)用擴(kuò)展函數(shù)
        }
    }

    class C1 : C() {
        override fun D.foo() {
            println("D.foo in C1")
        }

        override fun D1.foo() {
            println("D1.foo in C1")
        }
    }

    C().caller(D())   // 輸出 "D.foo in C"
    C1().caller(D())  // 輸出 "D.foo in C1" —— 分發(fā)接收者虛擬解析
    C().caller(D1())  // 輸出 "D.foo in C" —— 擴(kuò)展接收者靜態(tài)解析

是不是就很清楚了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 人生苦多,快來 Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,703評(píng)論 9 118
  • 第一部分Common Lisp介紹第1章 介紹一下Lisp你在學(xué)的時(shí)候覺得已經(jīng)明白了,寫的時(shí)候更加確信了解了,教別...
    geoeee閱讀 3,233評(píng)論 5 8
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,602評(píng)論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,136評(píng)論 25 708
  • 原文鏈接:https://github.com/EasyKotlin 值就是函數(shù),函數(shù)就是值。所有函數(shù)都消費(fèi)函數(shù),...
    JackChen1024閱讀 6,346評(píng)論 1 17

友情鏈接更多精彩內(nèi)容