變量
變量是存儲單項數(shù)據(jù)的容器,必須先聲明變量,才可以使用。
常見的數(shù)據(jù)類型: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ù)時,需要使用fun
關(guān)鍵字,并在 {}
中添加代碼用于執(zhí)行某個任務(wù)的指令。
聲明函數(shù)
如果不指定返回值類型,默認返回值類型是Unit
類型。Unit
表示函數(shù)不會返回值,所以不需要使用 return
語句。如果指定了返回值類型,則必須使用return
語句。
例如:
fun sum(num1: Int, num2: Int): Int{
return num1 + num2
}
// 按照形參傳遞
print(sum(2,1))
// 調(diào)用函數(shù)時為實參命名。使用具名實參時,您可以對實參重新排序,而不會影響輸出
// 按照具名實參傳遞
print(sum(num2 = 1,num1 = 2))
// 指定默認實參,以便在調(diào)用函數(shù)時省略該實參
// 如果沒有傳入 num1, 則num1按 10 來計算
fun sum(num1: Int = 10, num2: Int): Int{
return num1 + num2
}
條件語句
if/else 語句
例如 實現(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 語句
在 Kotlin 中,當處理多個分支時,可以使用 when 語句。類似 java 中的 switch 語句。
使用 when
語句實現(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
語句中多個條件,用英文逗號 (,) 處理。
when
語句中使用 in
關(guān)鍵字和一個值范圍,如需使用某個范圍內(nèi)的值,請?zhí)砑右粋€表示范圍起點的數(shù)字,后跟兩個不含空格的點,然后使用另一個表示范圍終點的數(shù)字作為結(jié)尾。
when
語句中使用 is
關(guān)鍵字作為條件,以檢查所評估值的數(shù)據(jù)類型。
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 表達式 和 when 表達式
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
,只有當您明確讓某個變量可以存儲 null
值時,該變量才屬于可為null
類型。如需在 Kotlin 中聲明可為null
的變量,您需要在相應(yīng)類型的末尾添加?
運算符
如果需要訪問可為 null
的變量時
可使用 ?.
安全調(diào)用運算符訪問可為 null 變量的方法或?qū)傩?br>
也可使用 !!
非 null 斷言運算符來訪問可為 null 的變量的方法或?qū)傩浴?? 使用!!
必須保證變量不為null,否則會在執(zhí)行期間崩潰
也可結(jié)合 if/else
語句使用
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor.length)//錯誤 執(zhí)行出錯
println(favoriteActor?.length)//對于可為null類型的值
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 運算符
?:
Elvis 運算符可以與?.
安全調(diào)用運算符搭配使用。如果搭配使用?:
Elvis 運算符,您便可以在?.
安全調(diào)用運算符返回null
時添加默認值。這與if/else
表達式類似,但更為常用。
如果該變量不為null
,則執(zhí)行?:
Elvis 運算符之前的表達式;如果變量為 null
,則執(zhí)行?:
Elvis 運算符之后的表達式。
個人認為:?:
可以理解為三目運算符
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = favoriteActor?.length ?: 0
println("The number of characters in your favorite actor's name is $lengthOfName.")
類和對象
類定義以class
關(guān)鍵字開頭,后面依次跟名稱和一對大括號。左大括號之前的語法部分也稱為類標頭。在大括號之間,您可以指定類的屬性和函數(shù)。
類由以下三大部分組成:
屬性:用于指定類對象屬性的變量。
方法:包含類的行為和操作的函數(shù)。
構(gòu)造函數(shù):一種特殊的成員函數(shù),用于在定義類的整個程序中創(chuàng)建類的實例
示例:
// 定義類
class SmartDevice {
// 定義類的屬性
val name = "Android TV"
val category = "Entertainment"
var deviceStatus = "online"
// 定義類的方法
fun turnOn(){
println("Smart device is turned on.")
}
fun turnOff(){
println("Smart device is turned off.")
}
}
fun main(){
// 創(chuàng)建類的對象
val smartTvDevice = SmartDevice()
//調(diào)用類的屬性
println("Device name is: ${smartTvDevice.name}")
// 調(diào)用類的方法
smartTvDevice.turnOn()
smartTvDevice.turnOff()
}
構(gòu)造函數(shù)
輔助構(gòu)造函數(shù)聲明:輔助構(gòu)造函數(shù)定義以constructor
關(guān)鍵字開頭,后跟圓括號。可視情況在圓括號中包含輔助構(gòu)造函數(shù)所需的形參。
主要構(gòu)造函數(shù)初始化:初始化以冒號開頭,后面依次跟this
關(guān)鍵字和一對圓括號。可視情況在圓括號中包含主要構(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"
}
}
...
}
類之間的關(guān)系
Kotlin 中,所有類默認都是最終類,也就是說您無法擴展這些類,因此必須定義類之間的關(guān)系,可在父類中的 class
關(guān)鍵字之前,添加open
關(guān)鍵字對其父類進行擴展。同樣,如果需要繼承父類中的方法,也需要在方法前添加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)鍵字會告知 Kotlin 運行時去執(zhí)行子類所定義方法中包含的代碼。
override fun turnOff() {
deviceStatus = "off"
brightnessLevel = 0
println("Smart Light turned off")
}
fun increaseBrightness() {
brightnessLevel++
}
}
使用super
關(guān)鍵字在子類中重復(fù)使用父類代碼
可見性修飾符
Kotlin 提供了以下四種可見性修飾符:
public:默認的可見性修飾符。可讓系統(tǒng)在任何位置訪問聲明。對于您想在類外部使用的屬性和方法,請標記為 public。
private:可讓系統(tǒng)在相同類或源文件中訪問聲明。
某些屬性和方法可能僅在類的內(nèi)部使用,而且您不一定想讓其他類使用。您可以使用 private 可見性修飾符標記這些屬性和方法,以確保其他類不會意外訪問它們。
protected:可讓系統(tǒng)在子類中訪問聲明。對于您想在定義它們的類及其子類中使用的屬性和方法,請使用 protected 可見性修飾符進行標記。
internal:可讓系統(tǒng)在相同模塊中訪問聲明。internal 修飾符與 private 類似,但您可以從類的外部訪問內(nèi)部屬性和方法,只要是在相同模塊中進行訪問即可
定義屬性委托
創(chuàng)建屬性委托的語法是以變量聲明開頭,后面依次跟 by
關(guān)鍵字以及用于為屬性處理getter
和setter
函數(shù)的委托對象。
若要實現(xiàn)您可以委托實現(xiàn)的目標類,您必須熟悉接口。接口是實現(xiàn)它的類必須遵循的協(xié)議,側(cè)重于操作的“內(nèi)容”,而不是操作的“方式”。簡而言之,接口可幫助您實現(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)
...
}