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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Kotlin 繼承 > 原文: [https://www.programiz.com/kotlin-programming/inheritance](https://www.programiz.com/kotlin-programming/inheritance) #### 在本文中,您將學習繼承。 更具體地說,什么是繼承以及如何在 Kotlin 中實現繼承(借助示例)。 繼承是面向對象編程的主要功能之一。 它允許用戶從現有類(基類)創建一個新類(派生類)。 派生類繼承了基類的所有功能,并且可以擁有自己的其他功能。 在詳細介紹 Kotlin 繼承之前,建議您閱讀以下兩篇文章: * [Kotlin 類和對象](/kotlin-programming/class-objects "Kotlin OOP") * [Kotlin 主要構造器](/kotlin-programming/constructors#primary " Kotlin Constructors and Initializers") * * * ## 為什么是繼承? 假設在您的應用中,您需要三個字符-一個**數學老師**,一個**足球運動員**和一個**商人**。 由于所有角色都是人,因此他們可以走路和說話。 但是,他們也有一些特殊技能。 數學老師可以**教數學**,足球運動員可以**踢足球**,商人可以**經營業務**。 您可以單獨創建三個可以走路,說話和執行其特殊技能的類。 ![Example of classes sharing same features without the use of inheritance.](https://img.kancloud.cn/dc/66/dc668b927ce4d5d4625b616ae329385b_599x174.png) 在每個類中,您將為每個角色復制相同的步行和說話代碼。 如果要添加新函數`eat`,則需要為每個字符實現相同的代碼。 這很容易導致出錯(復制時)和重復代碼。 如果我們有一個`Person`類,它具有基本的功能,例如說話,走路,吃飯,睡覺,并根據我們的角色向這些功能添加特殊技能,那就容易得多。 這是使用繼承完成的。 ![Example of inheritance in OOP](https://img.kancloud.cn/e0/16/e01685b4a39737847619fa3e2ef968f8_596x322.png) 使用繼承,現在您不必為每個類的`walk()`,`talk()`和`eat()`實現相同的代碼。 您只需要**繼承它們**。 因此,對于`MathTeacher`(派生類),您可以繼承`Person`(基類)的所有函數并添加新函數`teachMath()`。 同樣,對于`Footballer`類,您可以繼承`Person`類的所有函數,并添加新函數`playFootball()`,依此類推。 這使您的代碼更簡潔,易于理解和可擴展。 **重要的是要記住**:在處理繼承時,每個派生類都應滿足“**是**”基類的條件。 在以上示例中,`MathTeacher`**是**`Person`,`Footballer`**是**`Person`。 您不能有`Businessman`**是**`Business`這類的東西。 * * * ## Kotlin 繼承 讓我們嘗試在代碼中實現以上討論: ```kt open class Person(age: Int) { // code for eating, talking, walking } class MathTeacher(age: Int): Person(age) { // other features of math teacher } class Footballer(age: Int): Person(age) { // other features of footballer } class Businessman(age: Int): Person(age) { // other features of businessman } ``` 在此,`Person`是基類,并且`MathTeacher`,`Footballer`和`Businessman`類是從`Person`類派生的。 注意,在基類`Person`之前的關鍵字`open`。 這一點很重要。 默認情況下,Kotlin 中的類是最終的。 如果您熟悉 Java,那么您將知道最終類不能被子類化。 通過在類上使用開放修飾符,編譯器允許您從其派生新類。 * * * ## 示例:Kotlin 繼承 ```kt open class Person(age: Int, name: String) { init { println("My name is $name.") println("My age is $age") } } class MathTeacher(age: Int, name: String): Person(age, name) { fun teachMaths() { println("I teach in primary school.") } } class Footballer(age: Int, name: String): Person(age, name) { fun playFootball() { println("I play for LA Galaxy.") } } fun main(args: Array<String>) { val t1 = MathTeacher(25, "Jack") t1.teachMaths() println() val f1 = Footballer(29, "Christiano") f1.playFootball() } ``` 運行該程序時,輸出為: ```kt My name is Jack. My age is 25 I teach in primary school. My name is Cristiano. My age is 29 I play for LA Galaxy. ``` 這里,從`Person`類派生兩個類`MathTeacher`和`Footballer`。 `Person`類的主要構造器聲明了兩個屬性:`age`和`name`,并且它具有一個初始化塊。 基類`Person`的初始化塊(和成員函數)可以由派生類(`MathTeacher`和`Footballer`)的對象訪問。 派生類`MathTeacher`和`Footballer`分別具有自己的成員函數`teachMaths()`和`playFootball()`。 這些函數只能從其各自類別的對象中訪問。 * * * 創建`MathTeacher`類的對象`t1`時, ```kt val t1 = MathTeacher(25, "Jack") ``` 參數被傳遞給主構造器。 在 Kotlin 中,創建對象時會調用`init`塊。 由于`MathTeacher`是從`Person`類派生的,因此它將在基類(`Person`)中查找初始化塊并執行它。 如果`MathTeacher`具有初始化塊,則編譯器還將執行派生類的初始化塊。 接下來,使用`t1.teachMaths()`語句調用對象`t1`的`teachMaths()`函數。 創建`Footballer`類的對象`f1`時,程序的工作原理類似。 它執行基類的 init 塊。 然后,使用語句`f1.playFootball()`調用`Footballer`類的`playFootball()`方法。 * * * ## 重要說明:Kotlin 繼承 * 如果類具有主要構造器,則必須使用主要構造器的參數來初始化基類。 在上面的程序中,兩個派生類都有兩個參數`age`和`name`,并且這兩個參數都在基類的主構造器中初始化。 這是另一個示例: ```kt open class Person(age: Int, name: String) { // some code } class Footballer(age: Int, name: String, club: String): Person(age, name) { init { println("Football player $name of age $age and plays for $club.") } fun playFootball() { println("I am playing football.") } } fun main(args: Array<String>) { val f1 = Footballer(29, "Cristiano", "LA Galaxy") } ``` 在此,派生類的主要構造器具有 3 個參數,而基類具有 2 個參數。 請注意,基類的兩個參數均已初始化。 * 在沒有主構造器的情況下,每個基類都必須初始化基函數(使用`super`關鍵字),或者委托給另一個執行該操作的構造器。 例如, ```kt fun main(args: Array<String>) { val p1 = AuthLog("Bad Password") } open class Log { var data: String = "" var numberOfData = 0 constructor(_data: String) { } constructor(_data: String, _numberOfData: Int) { data = _data numberOfData = _numberOfData println("$data: $numberOfData times") } } class AuthLog: Log { constructor(_data: String): this("From AuthLog -> + $_data", 10) { } constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) { } } ``` 要了解有關該程序如何工作的更多信息,請訪問 [Kotlin 二級構造器](/kotlin-programming/constructors#secondary "Kotlin Secondary Constructor")。 * * * ## 覆蓋成員的函數和屬性 如果基類和派生類包含名稱相同的成員函數(或屬性),則可能需要使用`override`關鍵字覆蓋派生類的成員函數,并對基類使用`open`關鍵字。 * * * ## 示例:覆蓋成員函數 ```kt // Empty primary constructor open class Person() { open fun displayAge(age: Int) { println("My age is $age.") } } class Girl: Person() { override fun displayAge(age: Int) { println("My fake age is ${age - 5}.") } } fun main(args: Array<String>) { val girl = Girl() girl.displayAge(31) } ``` 運行該程序時,輸出為: ```kt My fake age is 26. ``` 在此,`girl.displayAge(31)`調用派生類`Girl`的`displayAge()`方法。 * * * 您可以通過類似的方式覆蓋基類的屬性。 在檢查以下示例之前,請訪問 [Kotlin 獲取器和設置器](/kotlin-programming/getters-setters "Kotlin getters and setters")在 Kotlin 中的工作方式。 ```kt // Empty primary constructor open class Person() { open var age: Int = 0 get() = field set(value) { field = value } } class Girl: Person() { override var age: Int = 0 get() = field set(value) { field = value - 5 } } fun main(args: Array<String>) { val girl = Girl() girl.age = 31 println("My fake age is ${girl.age}.") } ``` 運行該程序時,輸出為: ```kt My fake age is 26. ``` 如您所見,我們分別在派生類和基類中為`age`屬性使用了`override`和`open`關鍵字。 * * * ### 從派生類調用基類成員 您可以使用`super`關鍵字從派生類中調用基類的函數(和訪問屬性)。 這是如何做: ```kt open class Person() { open fun displayAge(age: Int) { println("My actual age is $age.") } } class Girl: Person() { override fun displayAge(age: Int) { // calling function of base class super.displayAge(age) println("My fake age is ${age - 5}.") } } fun main(args: Array<String>) { val girl = Girl() girl.displayAge(31) } ``` 運行該程序時,輸出為: ```kt My age is 31. My fake age is 26. ```
                  <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>

                              哎呀哎呀视频在线观看