變量
變量是存儲(chǔ)單項(xiàng)數(shù)據(jù)的容器,必須先聲明變量,才可以使用。
常見(jiàn)的數(shù)據(jù)類(lèi)型:Int、Double、String、Boolean
val
關(guān)鍵字用于定義只讀變量,一旦賦值就不能更改。
var
關(guān)鍵字用于定義可變變量。
在Kotlin
中,建議盡可能使用val
,而不是var
聲明變量
例如:
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ù)
如果不指定返回值類(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ǔ)句
例如 實(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ǔ)句。
使用 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ǔ)句使用
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á)式。
個(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)鍵字以及用于為屬性處理getter
和setter
函數(shù)的委托對(duì)象。
若要實(shí)現(xiàn)您可以委托實(shí)現(xiàn)的目標(biāo)類(lèi),您必須熟悉接口。接口是實(shí)現(xiàn)它的類(lèi)必須遵循的協(xié)議,側(cè)重于操作的“內(nèi)容”,而不是操作的“方式”。簡(jiǎn)而言之,接口可幫助您實(shí)現(xiàn)抽象。
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)
...
}