<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                **Kotlin是一種靜態類型語言,我們創建的每個對象不僅具有運行時,還具有編譯時類型,開發人員必須明確指定(在Kotlin中可以推斷)**。在**使用擴展函數時,要清楚地了解靜態和動態調度之間的區別**。 ### 1.靜態與動態調度 由于這個內容可能大部分讀者都沒有接觸過,所以我們舉一個Java例子,幫助大家理解。已知我們有以下類: ``` class Base { public void fun() { System.out.println(("I'm Base foo! ")); } } class Extended extends Base { @Override public void fun() { System.out.println(("I'm Extended foo! ")); } } Base base = new Extended(); base.fun(); ``` 對于以上代碼,我們**聲明一個名為base的變量,它具有編譯時類型Base和運行時類型Extended**。當我們調用時,base.foo()將動態調度該方法,這意味著運行時類型(Extended)的方法被調用。 當我們調用重載方法時,調度變為靜態并且僅取決于編譯時類型。 ``` void foo(Base base) { ... } void foo(Extended extended) { ... } public static void main(String[] args) { Base base = new Extended(); foo(base); } ``` 在這種情況下,**即使base本質上是Extended的實例,最終還是會執行Base的方法**。 ### **2. 擴展函數始終靜態調度** 可能你會好奇,這和擴展有什么關系?我們知道,擴展函數都有一個接收器(receiver),由于接收器實際上只是字節代碼中編譯方法的參數,因此你可以重載它,但不能覆蓋它。這可能是**成員和擴展函數之間最重要的區別:前者是動態調度的,后者總是靜態調度的**。 為了便于理解,我們舉一個例子: ``` open class Base class Extended: Base() fun Base.foo() = "I'm Base.foo! " fun Extended.foo() = "I'm Extended.foo! " fun main(args: Array<String>) { val instance: Base = Extended() val instance2 = Extended() println(instance.foo()) println(instance2.foo()) } ``` 正如我們所說,**由于只考慮了編譯時類型,第1個打印將調用`Base.foo()`,而第2個打印將調用`Extended.foo()`**。 ``` I'm Base.foo! I'm Extended.foo! ``` ### 3.類中的擴展函數 **如果我們在類的內部聲明擴展函數,那么它將不是靜態的。如果該擴展函數加上open關鍵字,我們可以在子類中進行重寫(override)**。這是否意味著它將被動態調度?這是一個比較尷尬的問題:**當在類內部聲明擴展函數時,它同時具有調度接收器和擴展接收器**。 ***** **調度接收器和擴展接收器**的概念 * **擴展接收器(extension receiver)**:與Kotlin擴展密切相關的接收器,表示**我們為其定義擴展的對象**。 * **調度接收器(dispatch receiver)**:擴展被聲明為成員時存在的一種特殊接收器,它**表示聲明擴展名的類的實例**。 ***** ``` class X { fun Y.foo() = " I'm Y.foo" } ``` 在上面的例子中,**X是調度接收器而Y是擴展接收器。如果將擴展函數聲明為open,則它的調度接收器只能是動態的,而擴展接收器總是在編譯時解析**。 這樣說你可能還不是很明白,我們還是舉一個例子幫助理解: ``` open class Base class Extended : Base() open class X { open fun Base.foo() { println("I'm Base.foo in X") } open fun Extended.foo() { println("I'm Extended.foo in X") } fun deal(base: Base) { base.foo() } } class Y : X() { override fun Base.foo() { println("I'm Base.foo in Y") } override fun Extended.foo() { println("I'm Extended.foo in Y") } } X().deal(Base()) // 輸出I'm Base.foo in X Y().deal(Base()) // 輸出I'm Base.foo in Y — 即dispatch receiver被動態處理 X().deal(Extended()) // 輸出I'm Base.foo in X — 即extension receiver被靜態處理 Y().deal(Extended()) // 輸出I'm Base.foo in Y ``` 聰明的你可能會注意到,**Extended擴展函數始終沒有被調用,并且此行為與我們之前在靜態調度例子中所看到的一致。決定兩個Base類擴展函數執行哪一個,直接因素是執行deal方法的類的運行時類型**。 通過以上例子,我們可以總結出擴展函數幾個需要注意的地方: * **如果該擴展函數是頂級函數或成員函數,則不能被覆蓋**; * **我們無法訪問其接收器的非公共屬性**; * **擴展接收器總是被靜態調度**。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看