<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 1. 泛型 **泛型**是一種編譯時的安全檢測機制,它允許在定義類、接口、方法時使用類型參數,聲明的類型參數在使用時用具體的類型來替換。泛型的**本質是參數化類型**,也就是說所操作的數據類型被指定為一個參數。其實在之前的小節中也用到過泛型,且其用法和`Java`中基本一致,所以這里就簡略介紹。 # 2. 泛型類 **泛型符號**可以是滿足`Kotlin`命名規則的任意字符,甚至可以是某一個單詞。比如下面的案例: ~~~ data class KotlinDemo<N, A>(var name: N, var age: A) { override fun toString(): String { return "KotlinDemo(name=$name, age=$age)" } } fun main() { var demo = KotlinDemo<String, Int>("張三", 24) println(demo) } ~~~ 結果: ``` KotlinDemo(name=張三, age=24) ``` 至于用在方法和接口上的使用類似,這里就不再繼續給出案例。 # 3. 泛型約束 注意到上面的方式僅僅只是簡單的應用,而實際上還有泛型約束。比如在`Java`中提供了`super`和`extends`關鍵字來進行。在`Kotlin`中類似的可以進行對類型的約束。 - `<? extends類或接口> ` 類比于: `<T:類或接口>`。可以理解為泛型的上界,因為在`Kotlin`中使用`:`來表示繼承關系。 比如下面的案例: ~~~ open class Animal{ var weight = 30 } // 繼承 class Cat: Animal() { var name = "Cat" override fun toString(): String { return "Cat(name='$name', weight=$weight)" } } class KotlinDemo<T: Animal> (animal: T){ private var demo: T? = null init { if(this.demo == null) { this.demo = animal } } override fun toString(): String { return "KotlinDemo(demo=$demo)" } } fun main() { var demo = KotlinDemo<Cat>(Cat()) println(demo) } ~~~ 結果: ``` KotlinDemo(demo=Cat(name='Cat', weight=30)) ``` # 4. 協變與逆變 協變與逆變其實是`C#`語言`4.0`以后新增的高級特性,**協變**是將父類變為具體子類,協變類型作為消費者,只能讀取不能寫入,**逆變**是將子類變為具體父類,逆變作為生產者,只能寫入不能讀取。 - **協變**,父類變子類,只能讀取(`out`); - **逆變**,子類變父類,只能寫入(`in`); 對于`in`和`out`這兩個單詞的簡單理解記憶圖示: ![](https://img.kancloud.cn/de/d4/ded4f553c090c91072729af78abe8f1b_349x301.png) 上圖來自視頻:[Kotlin教程](https://www.bilibili.com/video/BV1wf4y1s7TG?p=114) 這么說起來比較抽象,這里直接給出兩個案例。 ## 4.1 案例一:逆變 ~~~ // 逆變,只寫,作為函數參數 interface Consumer<in T>{ fun consume(item: T) } open class Animal class Cat: Animal() class KotlinDemo2: Consumer<Animal> { override fun consume(item: Animal){ } } fun main() { var consumer1: Consumer<Cat> = KotlinDemo2() } ~~~ ## 4.2 案例二:協變 ~~~ // 協變,只讀,即僅作為返回值 interface Producer<out T>{ fun produce(): T } open class Animal class Cat: Animal() class KotlinDemo2: Producer<Animal> { override fun produce(): Animal{ return Animal() } } class KotlinDemo1: Producer<Cat> { override fun produce(): Cat { return Cat() } } fun main() { var consumer1: Producer<Animal> = KotlinDemo1() } ~~~ 父變子指的是:要求是`Animal`,但是賦值的為子類對象。 # 5. 泛型類型檢查 有時候我們需要對傳入的泛型的類型做一個檢查,而在`Java`中我們通常使用反射來獲取類型進而進行判斷,比如: ~~~ interface B<T>{ T getInstance(T t); } public class A<T> implements B<T>{ @Override public T getInstance(T t) { if(t.getClass().getName() .equals("com.kotlinLearn.Animal")){ return t; } return (T) new Cat(); } public static void main(String[] args) { A<Animal> a = new A<>(); Animal instance = a.getInstance(new Cat()); System.out.println(instance.getClass().getName()); } } ~~~ 結果: ``` com.kotlinLearn.Cat ``` 而在`Kotlin`中就不需要這么麻煩,可以直接使用關鍵字`inline`和`reified`進行判斷: ~~~ open class Animal class Cat: Animal() class B{ inline fun<reified T> getInstance(item: () -> T): T { val animal = Animal() return if(animal is T){ animal } else{ item() } } } ~~~
                  <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>

                              哎呀哎呀视频在线观看