Kotlin學習筆記(四):Kotlin中的類與對象

一、簡介

Kotlin中使用關鍵字class 聲明類,後面緊跟類名 。Kotlin中的類默認是public final的,所以如果不需要類爲final的時候,需要使用open關鍵字修飾類,如果沒有聲明父類。則父類默認爲Any類。

//定義一個空類
open class Animal

interface Run

//繼承類或接口時,使用 : 隔開,父類和接口間使用 , 隔開
class Dog : Animal(), Run

二、構造函數

1. 主構造器

主構造器放在類名後,不能包含任何代碼,初始化代碼可以放在初始化代碼段中,初始化代碼段使用init關鍵字作爲前綴。
注意:主構造器的參數可以在初始化代碼段中使用,可以通過主構造器來定義屬性並初始化屬性值(可以是varval)。

class Dog constructor(val age: Int, val name: String){

    init {
        println("Dog $name is $age years old.")
    }

}

如果構造器有註解,或者有可見度修飾符,則constructor關鍵字是必須的,註解和修飾符放在它之前,否則constructor可以省略不寫。

2. 創建實例

fun main(args: Array<String>) {
    val dog = Dog(2,"Irving")
}

3.次級構造函數

類的次級構造函數使用constructor修飾。

class Cat {
    
    constructor(age: Int, name: String){
        println("Cat $name is $age years old")
    }
    
}

如果類有主構造器,則每個次級構造函數都需要直接或間接的代理此主構造器。在同一個類中代理另一個構造函數使用this關鍵字。

class Cat(age: Int) {

    constructor(age: Int, name: String): this(age){
        println("Cat $name is $age years old")
    }

    constructor(age: Int, name: String, type: Int): this(age, name){
        println("Cat $name is $age years old")
    }
    
}

三、訪問修飾符

  1. private:修飾類的時候,表示該類中所有成員都是私有的。修飾成員的時候,表示該成員是該類私有的。
  2. protected:只能用以修改類的成員,表示只有該類和它的子類可以訪問該成員。
  3. public:所有類均可訪問。
  4. internal:表示只有該模塊(moudle)內的類能訪問。

四、伴生對象

通過companion object聲明伴生對象,必須寫在一個類的內部,作爲該類的伴生對象,編譯器編譯時會在該類中生成一個靜態的Companion對象,然後調用該靜態對象的成員。伴生對象中的屬性和方法可以理解爲Java中的靜態變量和靜態方法,可以直接通過類名.屬性/方法調用,如果是Java類中調用時通過類名.Companion.屬性/方法調用

	class Bird{

	    companion object {
	        const val BIRD_NAME = "Irving"
	
	        fun getBirdName(): String = BIRD_NAME 
	    }

	}

除了使用object關鍵字聲明一個單例類之外,使用伴生對象可以很方便的創建單例對象。

	class Person{
	
	    companion object {
	        fun get(): Person = Holder.instance
	    }
	
	    private object Holder{
	        val instance = Person()
	    }
	
	}

五、Kotlin中的動態代理

Kotlin中通過使用by關鍵字可以很方便的使用動態代理。

interface People {
    fun sayHello()
}

//目標類
class Man : People {
    override fun sayHello() {
        println("Hello")
    }
}

//代理類
class Irving(people: People) : People by people 

fun main(args: Array<String>) {
    val irving = Irving(Man())
    irving.sayHello()
}

Kotlin會將動態代理編譯爲靜態代理去調用,所以Kotlin的動態代理比Java的動態代理效率高,因爲Java的動態代理本質上是通過反射去調用的。

六、數據類

可以使用data關鍵字聲明一個數據類,數據類是public final的,所以不可以被繼承(需要繼承時可以使用密封類)。編譯器會爲數據類的所有屬性生成getter()/setter()方法,並且會重寫toString()hashCode()equals()copy()這些方法。

data class User(
    var id: Int,
    var name: String,
    var gender: Int
)

七、密封類

密封類可以理解爲一個增強的枚舉類,密封類和它的子類必須寫在同一個文件中,增強的地方就是密封類的子類可以擴展,從而更加靈活。

sealed class Hello {
    object UP : Hello()
    object DOWN : Hello()
    object LEFT : Hello()
    object RIGHT : Hello()
    class Irving(var age: Int) : Hello()
}

fun test(hello: Hello) {
    when (hello) {
        Hello.UP -> println("UP")
        Hello.DOWN -> println("DOWN")
        Hello.LEFT -> println("LEFT")
        Hello.RIGHT -> println("RIGHT")
        is Hello.Irving -> println(hello.age)
    }
}

fun main(args: Array<String>) {
    test(Hello.Irving(11))
}
發佈了167 篇原創文章 · 獲贊 233 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章