Kotlin 基礎(chǔ) 筆記

變量

變量是存儲(chǔ)單項(xiàng)數(shù)據(jù)的容器,必須先聲明變量,才可以使用。
常見(jiàn)的數(shù)據(jù)類(lèi)型:Int、Double、String、Boolean

val關(guān)鍵字用于定義只讀變量,一旦賦值就不能更改。
var關(guān)鍵字用于定義可變變量。
Kotlin中,建議盡可能使用val,而不是var

聲明變量


image.png

例如:

val count: Int = 2 // 不可變變量
println("this count is $count") //$count 輸出變量

var number: Int = 2 // 可變變量

number++

函數(shù)

聲明函數(shù)時(shí),需要使用fun關(guān)鍵字,并在 {}中添加代碼用于執(zhí)行某個(gè)任務(wù)的指令。

聲明函數(shù)


image.png

如果不指定返回值類(lèi)型,默認(rèn)返回值類(lèi)型是Unit 類(lèi)型。Unit表示函數(shù)不會(huì)返回值,所以不需要使用 return 語(yǔ)句。如果指定了返回值類(lèi)型,則必須使用return 語(yǔ)句。

例如:

fun sum(num1: Int, num2: Int): Int{
        return num1 + num2
 }

// 按照形參傳遞
print(sum(2,1))

// 調(diào)用函數(shù)時(shí)為實(shí)參命名。使用具名實(shí)參時(shí),您可以對(duì)實(shí)參重新排序,而不會(huì)影響輸出
// 按照具名實(shí)參傳遞
 print(sum(num2 = 1,num1 = 2))

// 指定默認(rèn)實(shí)參,以便在調(diào)用函數(shù)時(shí)省略該實(shí)參
// 如果沒(méi)有傳入 num1, 則num1按 10 來(lái)計(jì)算
fun sum(num1: Int = 10, num2: Int): Int{
        return num1 + num2
 }

條件語(yǔ)句

if/else 語(yǔ)句

image.png

例如 實(shí)現(xiàn)紅綠燈

fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}

when 語(yǔ)句

在 Kotlin 中,當(dāng)處理多個(gè)分支時(shí),可以使用 when 語(yǔ)句。類(lèi)似 java 中的 switch 語(yǔ)句。


image.png

使用 when 語(yǔ)句實(shí)現(xiàn)紅綠燈

fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

when語(yǔ)句中多個(gè)條件,用英文逗號(hào) (,) 處理。
when語(yǔ)句中使用 in關(guān)鍵字和一個(gè)值范圍,如需使用某個(gè)范圍內(nèi)的值,請(qǐng)?zhí)砑右粋€(gè)表示范圍起點(diǎn)的數(shù)字,后跟兩個(gè)不含空格的點(diǎn),然后使用另一個(gè)表示范圍終點(diǎn)的數(shù)字作為結(jié)尾。
when語(yǔ)句中使用 is關(guān)鍵字作為條件,以檢查所評(píng)估值的數(shù)據(jù)類(lèi)型。

fun main() {
    val x: Any = 20

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
if/else 表達(dá)式 和 when 表達(dá)式
fun main() {
    val trafficLightColor = "Black"

    val message =
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"

    println(message)
}

fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Proceed with caution."
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
    println(message)
}

Kotlin 中的null

kotlin 不允許為變量賦值為 null,只有當(dāng)您明確讓某個(gè)變量可以存儲(chǔ) null 值時(shí),該變量才屬于可為null類(lèi)型。如需在 Kotlin 中聲明可為null的變量,您需要在相應(yīng)類(lèi)型的末尾添加?運(yùn)算符

如果需要訪問(wèn)可為 null 的變量時(shí)
可使用 ?. 安全調(diào)用運(yùn)算符訪問(wèn)可為 null 變量的方法或?qū)傩?br> 也可使用 !! 非 null 斷言運(yùn)算符來(lái)訪問(wèn)可為 null 的變量的方法或?qū)傩浴?? 使用!!必須保證變量不為null,否則會(huì)在執(zhí)行期間崩潰
也可結(jié)合 if/else 語(yǔ)句使用

image.png
fun main() {
    var favoriteActor: String? = "Sandra Oh"

    println(favoriteActor.length)//錯(cuò)誤 執(zhí)行出錯(cuò)

    println(favoriteActor?.length)//對(duì)于可為null類(lèi)型的值

    println(favoriteActor!!.length)

    if (favoriteActor != null) {
      println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")  }
    }

    val lengthOfName = if(favoriteActor != null) {
      favoriteActor.length
    } else {
      0
    }
使用 ?: Elvis 運(yùn)算符

?: Elvis 運(yùn)算符可以與?.安全調(diào)用運(yùn)算符搭配使用。如果搭配使用?:Elvis 運(yùn)算符,您便可以在?.安全調(diào)用運(yùn)算符返回null 時(shí)添加默認(rèn)值。這與if/else 表達(dá)式類(lèi)似,但更為常用。

如果該變量不為null,則執(zhí)行?:Elvis 運(yùn)算符之前的表達(dá)式;如果變量為 null,則執(zhí)行?:Elvis 運(yùn)算符之后的表達(dá)式。

image.png

個(gè)人認(rèn)為:?:可以理解為三目運(yùn)算符

   val favoriteActor: String? = "Sandra Oh"

    val lengthOfName = favoriteActor?.length ?: 0

    println("The number of characters in your favorite actor's name is $lengthOfName.")

類(lèi)和對(duì)象

類(lèi)定義以class關(guān)鍵字開(kāi)頭,后面依次跟名稱(chēng)和一對(duì)大括號(hào)。左大括號(hào)之前的語(yǔ)法部分也稱(chēng)為類(lèi)標(biāo)頭。在大括號(hào)之間,您可以指定類(lèi)的屬性和函數(shù)。

類(lèi)由以下三大部分組成:
屬性:用于指定類(lèi)對(duì)象屬性的變量。
方法:包含類(lèi)的行為和操作的函數(shù)。
構(gòu)造函數(shù):一種特殊的成員函數(shù),用于在定義類(lèi)的整個(gè)程序中創(chuàng)建類(lèi)的實(shí)例

示例:

// 定義類(lèi)
class SmartDevice {
    // 定義類(lèi)的屬性
    val name = "Android TV"
    val category = "Entertainment"
    var deviceStatus = "online"

    // 定義類(lèi)的方法
    fun turnOn(){
        println("Smart device is turned on.")
    }

    fun turnOff(){
        println("Smart device is turned off.")
    }
}
fun main(){
    // 創(chuàng)建類(lèi)的對(duì)象
    val smartTvDevice = SmartDevice()

    //調(diào)用類(lèi)的屬性
    println("Device name is: ${smartTvDevice.name}")

    // 調(diào)用類(lèi)的方法
    smartTvDevice.turnOn()
    smartTvDevice.turnOff()
}
構(gòu)造函數(shù)

輔助構(gòu)造函數(shù)聲明:輔助構(gòu)造函數(shù)定義以constructor 關(guān)鍵字開(kāi)頭,后跟圓括號(hào)。可視情況在圓括號(hào)中包含輔助構(gòu)造函數(shù)所需的形參。

主要構(gòu)造函數(shù)初始化:初始化以冒號(hào)開(kāi)頭,后面依次跟this 關(guān)鍵字和一對(duì)圓括號(hào)。可視情況在圓括號(hào)中包含主要構(gòu)造函數(shù)所需的形參。

class SmartDevice(val name: String, val category: String) {
    var deviceStatus = "online"

    // 主要構(gòu)造函數(shù)
    constructor(name: String, category: String, statusCode: Int) : this(name, category) {
        deviceStatus = when (statusCode) {
            0 -> "offline"
            1 -> "online"
            else -> "unknown"
        }
    }
    ...
}
類(lèi)之間的關(guān)系

Kotlin 中,所有類(lèi)默認(rèn)都是最終類(lèi),也就是說(shuō)您無(wú)法擴(kuò)展這些類(lèi),因此必須定義類(lèi)之間的關(guān)系,可在父類(lèi)中的 class關(guān)鍵字之前,添加open關(guān)鍵字對(duì)其父類(lèi)進(jìn)行擴(kuò)展。同樣,如果需要繼承父類(lèi)中的方法,也需要在方法前添加open 關(guān)鍵字。

open class SmartDevice {
    ...
    var deviceStatus = "online"

    open fun turnOn() {
        // function body
    }

    open fun turnOff() {
        // function body
    }
}
class SmartLightDevice(name: String, category: String) :
    SmartDevice(name = name, category = category) {

    var brightnessLevel = 0

    override fun turnOn() {
        deviceStatus = "on"
        brightnessLevel = 2
        println("$name turned on. The brightness level is $brightnessLevel.")
    }

    // override 關(guān)鍵字會(huì)告知 Kotlin 運(yùn)行時(shí)去執(zhí)行子類(lèi)所定義方法中包含的代碼。
    override fun turnOff() {
        deviceStatus = "off"
        brightnessLevel = 0
        println("Smart Light turned off")
    }

    fun increaseBrightness() {
        brightnessLevel++
    }
}

使用super關(guān)鍵字在子類(lèi)中重復(fù)使用父類(lèi)代碼

可見(jiàn)性修飾符

Kotlin 提供了以下四種可見(jiàn)性修飾符:

public:默認(rèn)的可見(jiàn)性修飾符。可讓系統(tǒng)在任何位置訪問(wèn)聲明。對(duì)于您想在類(lèi)外部使用的屬性和方法,請(qǐng)標(biāo)記為 public。

private:可讓系統(tǒng)在相同類(lèi)或源文件中訪問(wèn)聲明。
某些屬性和方法可能僅在類(lèi)的內(nèi)部使用,而且您不一定想讓其他類(lèi)使用。您可以使用 private 可見(jiàn)性修飾符標(biāo)記這些屬性和方法,以確保其他類(lèi)不會(huì)意外訪問(wèn)它們。

protected:可讓系統(tǒng)在子類(lèi)中訪問(wèn)聲明。對(duì)于您想在定義它們的類(lèi)及其子類(lèi)中使用的屬性和方法,請(qǐng)使用 protected 可見(jiàn)性修飾符進(jìn)行標(biāo)記。

internal:可讓系統(tǒng)在相同模塊中訪問(wèn)聲明。internal 修飾符與 private 類(lèi)似,但您可以從類(lèi)的外部訪問(wèn)內(nèi)部屬性和方法,只要是在相同模塊中進(jìn)行訪問(wèn)即可

定義屬性委托

創(chuàng)建屬性委托的語(yǔ)法是以變量聲明開(kāi)頭,后面依次跟 by關(guān)鍵字以及用于為屬性處理gettersetter函數(shù)的委托對(duì)象。

image.png

若要實(shí)現(xiàn)您可以委托實(shí)現(xiàn)的目標(biāo)類(lèi),您必須熟悉接口。接口是實(shí)現(xiàn)它的類(lèi)必須遵循的協(xié)議,側(cè)重于操作的“內(nèi)容”,而不是操作的“方式”。簡(jiǎn)而言之,接口可幫助您實(shí)現(xiàn)抽象。

image.png
class RangeRegulator(
    initialValue: Int,
    private val minValue: Int,
    private val maxValue: Int
) : ReadWriteProperty<Any?, Int> {
    var fieldData = initialValue

    override fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return fieldData
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        if (value in minValue..maxValue) {
            fieldData = value
        }
    }
}
class SmartTvDevice(deviceName: String, deviceCategory: String) :
    SmartDevice(name = deviceName, category = deviceCategory) {

    private var speakerVolume by RangeRegulator(initialValue = 0, minValue = 0, maxValue = 100)

    private var channelNumber by RangeRegulator(initialValue = 1, minValue = 0, maxValue = 200)

    ...
}

class SmartLightDevice(deviceName: String, deviceCategory: String) :
    SmartDevice(name = deviceName, category = deviceCategory) {

    private var brightnessLevel by RangeRegulator(initialValue = 2, minValue = 0, maxValue = 100)

    ...

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容