1. 程式人生 > >從零開始學Kotlin-類和對象(5)

從零開始學Kotlin-類和對象(5)

int 文件中 cls 間接 main dcl this 調用 定義類

從零開始學Kotlin基礎篇系列文章

定義一個類

  • 定義一個類,使用關鍵字class聲明,後面跟類名(不使用new)

    class demo5 {//定義一個類,使用關鍵字class聲明,後面跟類名
    
        fun test() {//類中定義方法
        }
    
        class empty//定義一個空類
    }

定義類的屬性

  • 類的屬性可以使用var和val定義

    class demo5 {
        var name: String = "SiberinDante"
        var age: Int = 18
        val gender: String = "男"
    }
  • 創建類的實例以及獲取類中的屬性

    class demo5 {
        var name: String = "SiberinDante"
        var age: Int = 18
        val gender: String = "男"
        fun test() {
            val user = demo5()//創建類demo5的實例
            print(user.name)//輸出name
        }
    }

類的修飾符: classModifier 和 accessModifier

  • classModifier: 類屬性修飾符,標示類本身特性。

       abstract    // 抽象類  
       final       // 類不可繼承,默認屬性
       enum        // 枚舉類
       open        // 類可繼承,類默認是final的
       annotation  // 註解類
  • accessModifier: 訪問權限修飾符

    private    // 僅在同一個文件中可見
    protected  // 同一個文件中或子類可見
    public     // 所有調用的地方都可見
    internal   // 同一個模塊中可見

構造器:

  • Koltin 中的類可以有一個 主構造器,以及一個或多個次構造器,主構造器是類頭部的一部分,位於類名稱之後,主構造器中不能包含任何代碼

    class consClass constructor(tag: String) {}
  • 主構造器中不能包含任何代碼,初始化代碼可以放在初始化代碼段中,初始化代碼段使用 init 關鍵字作為前綴。

    class consClass constructor(name: String) {
        init {//初始化
        }
    }
  • 主構造器的參數可以在初始化代碼段中使用,也可以在類主體n定義的屬性初始化代碼中使用。

    class consClass constructor(name: String) {
    init {
        print("My name is $name")
    }
    }
  • 次級構造函數,使用前綴 constructor修飾

    class cinsClass1 {
        constructor(age: Int, name: String) {}
    }
  • 如果類有主構造函數,每個次構造函數都要直接或間接通過另一個次構造函數代理主構造函數。在同一個類中代理另一個構造函數使用 this 關鍵字:

    class consClass constructor(name: String) {
        constructor(name: String, age: Int) : this(name) {
            print("name is $name,age is $age")
        }
        constructor(name: String, age: Int, gender: String) : this(name, age) {
            print("name is $name,age is $age,gender is $gender")
        }
    }
  • 構造函數是 public 的,如果一個非抽象類沒有聲明構造函數(主構造函數或次構造函數),它會產生一個沒有參數的構造函數。如果你不想你的類有公共的構造函數,你就得聲明一個空的主構造函數:

    class consClass2 private constructor() {}
  • 在 JVM 虛擬機中,如果主構造函數的所有參數都有默認值,編譯器會生成一個附加的無參的構造函數,這個構造函數會直接使用默認值。

抽象類

  • 抽象類使用abstract修飾,抽象成員在類中不存在具體的實現。無需對抽象類或抽象成員標註open註解。

    open class BaseClass {
        open fun baseVoid() {}
    }
    abstract class SecondClass : BaseClass() {
        override abstract fun baseVoid()
    }

嵌套類

  • 類中嵌套一個類

    class OuterClass {//外部類
        class NestedClass {//嵌套類
            fun showName() = "SiberiaDante"
        }
    }
    fun main(args: Array<String>) {
        val name = OuterClass.NestedClass().showName() // 調用格式:外部類.嵌套類.嵌套類方法/屬性
        println("name is $name")
    }

內部類

  • 內部類使用 inner 關鍵字來表示。內部類會帶有一個對外部類的對象的引用,所以內部類可以訪問外部類成員屬性和成員函數。

    class OuterClass1 {
        private val age: Int = 18
        var name = "成員屬性"
        inner class InnerClass { //內部類
            fun showAge() = age  // 內部類直接訪問外部類成員
    
            fun innerTest() {
                val outerCls = this@OuterClass1 //創建外部類的實例
                println("獲取外部類成員變量" + outerCls.name)//內部類可以引用外部類的成員
            }
        }
    }
    fun main1(args: Array<String>) {
        val age = OuterClass1().InnerClass().showAge()
        println("My age is $age") 
        val demo2 = OuterClass1().InnerClass().innerTest()
        println(demo2)
    }

匿名內部類

  • 使用對象表達式來創建匿名內部類

    /**
     * 定義接口
     */
    interface TestInterface {
        fun testInterface()
    }
    class AnonymousClass {
        fun setInterFace(test: TestInterface) {
            test.testInterface()
        }
    }
    fun main2(args: Array<String>) {
        var anonymousClass = AnonymousClass()
        /**
         * 采用對象表達式來創建接口對象,即匿名內部類的實例。
         */
        anonymousClass.setInterFace(object : TestInterface {
            override fun testInterface() {
                println("對象表達式創建匿名內部類的實例")
            }
        })
    }

從零開始學Kotlin-類和對象(5)