文章目錄
- 1、安裝 Java 和 Kotlin 環境
- 2、程序代碼基本結構
- 3、變量的聲明與使用
- 4、數據類型
- 5、數字類型的運算
- 1)布爾類型
- 2)字符類型
- 3)字符串類型
- 6、 選擇結構
- 1)(if - else)
- 2) 選擇結構(when)——適用于多分支結構
- 7、循環結構
- 1)for
- 2)循環結構——while
- 8、函數的定義及使用
- 1)用 fun 關鍵字聲明
- 2)函數的調用
- 3)有參數的函數
- 4)有返回值的函數
- 5)全局變量
- 6)函數類型變量
- 1 變量可以接收函數
- 2 函數也可以接收函數
- 3 總結
- 9、類與對象
- 1) 類的定義與對象的創建
- 2) 對象的創建
- 3)對象的初始化
- 4)類的成員函數
- 5) 再談基本類型
- a、空值和空類型
- 6)修飾符
- 7)封裝
- 8)繼承
- 9)屬性的覆蓋——多態
- 10)接口
- 10、數組的創建與使用
- 11、集合類
- 1)數組局限性
- 2)集合的分類
- 3)集合簡介
1、安裝 Java 和 Kotlin 環境
2、程序代碼基本結構
fun main(args: Array<String>) {println("Hello World!")
}
- 注意點:Kotlin 嚴格區分大小寫
3、變量的聲明與使用
fun main(args: Array<String>) {var x = 30println(x)
}// 自動判斷變量類型
fun main(args: Array<String>) {var x = 30println(x)
}// 變量值賦值給變量
fun main(args: Array<String>) {var x = 30var y = xprintln(y)
}fun main(args: Array<String>) {var x = 30var y = x / 30println(y)
}fun main(args: Array<String>) {var x = 30var y = 70println(x + y)
}fun main(args: Array<String>) {var x = 30x = 20println(x)
}// 定義常量
fun main(args: Array<String>) {val x = 30 // 常量println(x)
}
4、數據類型
- Byte、Short、Int、Long
- Float、Double
val pi = 3.1415 // 默認推斷為 Double 類型
val one : Double = 1 // 這種寫法錯誤,無法編譯通過
val one : Double = 1.0 // 這種寫法是對的
val a : Float = 1.0f
- 與其他語言不同,Kotlin 中的數字類型沒有隱式轉換的操作
var a:Int = 1;
var b:Double = a; // 報錯,不能隱式轉換
5、數字類型的運算
1)布爾類型
var a: Boolean = false
2)字符類型
var c: Char = 'D'
3)字符串類型
// 字符串中的字符一旦確定是無法進行修改的var str: String = "Hello World"str = "Helle World" // 整體修改val text = "Hello\nWorld" // 字符串中換行,需要用到轉義字符
6、 選擇結構
1)(if - else)
if
if {}if {
} else {
}if
else if
else if
else if {if }// if-else 還可以用作結果判斷
var score = 2
var res = if (score > 60) "Yes" else "NO"
2) 選擇結構(when)——適用于多分支結構
//代碼結構
when (目標) {匹配值1 -> 代碼匹配值2 -> 代碼匹配值3 -> 代碼else -> { // 可以沒有else語句,類似于之前的 if-else if-else代碼 // 如果以上條件都不滿足,就進入else中}
}
val c = 'A'
when (c) {'A' -> println("尖子班")'B' -> println("中等班")'C' -> println("普通班")
}val c = 'A'
var value = when (c) {'A' -> 1'B' -> 2'C' -> 3else -> 0 // 要把所有能表示的情況都寫完才不會報錯(必加)
}val c : Boolean = true
var value = when (c) {true -> 1false -> 2 // 所有情況中只有這兩種情況所以不用加else
}// 某些值屬于同一種情況,可以使用逗號將其條件組成一行
var x = 0;
when (x) {0, 1 -> print("x == 0 or x == 1")else -> print("otherwise")
}// in 表示區間
var score = 10;
var grade= when (score) {// 使用 in 判斷目標標量值是否在指定范圍in 100 .. 90 -> {println();"優秀"}in 89 .. 80 -> "良好"in 79 .. 70 -> "及格"else -> "不及格"
}
7、循環結構
1)for
// 結構
for (遍歷出來的單個目標 in 可遍歷目標) 循環體
- 可遍歷目標
- 數組
- 區間
- 任何實現了運算符重載函數iterator的類
// 可遍歷目標為區間
for (i in 1..3)println(i)val range: IntRange = 1..3
for (i in range)println(i)val range: IntRange = 1..3
var x = 0
for (i in range) { // i 的作用范圍只在括號中println(i)x = i
}
// for 循環的嵌套
for (i in 0..2) {for (j in 0..2) {println("外層 $i,內層$j")}
}
2)循環結構——while
while (循環條件) 循環體
8、函數的定義及使用
1)用 fun 關鍵字聲明
fun 函數名稱([函數參數...]): 返回類型 {// 函數體
}
// 無返回值的兩種寫法
fun test(): Unit { // 返回值類型為Unit類比于其他語言中的void}fun text() {}
2)函數的調用
fun main() {test()
}
3)有參數的函數
fun text(m: String) { // m為參數名字,String為參數類型println(m)
}
4)有返回值的函數
fun text(a: Int, b: Int) : Int{ // a,b為參數,Int 為返回值類型return a + b
}// return 關鍵字在執行之后,后面的內容就不能繼續執行了
fun text(a: Int, b: Int) : Int{ // a,b為參數,Int 為返回值類型if (a + b > 10) return 10println("后面的函數")return a + b
}fun main(args: Array<String>) {test() // 參數有默認值之后可以不傳入實參
}
fun test(m: String = "HelloWorld") {println(m)
}fun main(args: Array<String>) {test("Hi") // 傳入值則形參為傳入的值
}
fun test(m: String = "HelloWorld") {println(m)
}fun sum(a: Int, b: Int): Int = a + b
fun sum(a: Int, b: Int) = a + b
5)全局變量
var a: Int = 10fun main(args: Array<String>) {println(a)
}fun test() {a = 20println(a)
}
var a: Int = 5get() = field + 10 // field代表變量a本身fun main(args: Array<String>) {println(a) // 此時打印出來的是15
}fun test() {a = 20println(a)
}
// 變臉中get和set屬性
// get 和 set 函數操作的就是本身變量的值
var a: Int = 5get() = field + 10 // field代表變量a本身set(value) { // value是賦值過來的參數println("我被賦值了")field = value}fun main(args: Array<String>) {a = 90println(a) // 此時打印出來的是15
}
6)函數類型變量
1 變量可以接收函數
// 接收String作為參數返回值為Int的函數類型var func: (String) -> Int // (String) -> Int:String作為參數,返回值為Int的函數給變量func存儲
2 函數也可以接收函數
fun test(func: (String) -> Int) { // 形參可以為函數類型的參數}fun test(other: (Int) -> String) {println(other(1)) //
}
3 總結
- 函數類型的變量可以當作函數使用
- 函數類型的變量也可以作為函數參數進行傳遞
9、類與對象
- 類是一個抽象的概念,對象指具體的
1) 類的定義與對象的創建
- 類的聲明使用關鍵字 class 聲明
class Student {
}
- kotlin 中的類可以添加一個主構造函數和一個或多個次要構造函數,主構造函數是類定義的一部分
class Student constructor(name: String, age: Int) { // 主構造函數的形參}// 主構造函數中的constructor也可以省去
class Student (name: String, age: Int) {}// 將構造函數的 參數變成類的屬性,在變量前面添加 var或者 val
class Student (var name: String, var age: Int) {}// 屬性寫在類里面的時候,必須要求有初始值
class Student () {var name: String = ""val age: Int = 8
}class Student (name: String, age: Int) { // 將傳進來的參數賦值給屬性var name: String = nameval age: Int = age
}
2) 對象的創建
- 對象的創建就是通過構造函數,調用構造函數
// 引用賦值
fun main(args: Array<String>) {var p1 = Student("小明", 18)var p2 = p1 // 引用賦值,指向的是同一個對象println(p2.name) // p2也就可以操控對象
}fun main(args: Array<String>) {var p1 = Student("小明", 18) // 通過構造函數創建對象var p2 = p1 // 引用賦值println(p2 == p1) // 判斷p1和p2是否指向的是同一個對象,輸出結果為true
}fun main(args: Array<String>) {var p1 = Student("小明", 18)var p2 = Student("小紅", 19)println(p2 == p1) // p1和p2指向的是兩個不同的對象,輸出結果為false
}fun main(args: Array<String>) {var p1 = Student("小明", 18)var p2 = Student("小明", 18)println(p2 == p1) // 輸出為false,通過構造函數創建出來的就是一個獨立的對象
}class Student (name: String, a ge: Int) { // 將傳進來的參數賦值給屬性var name: String = nameval age: Int = age
}
3)對象的初始化
- 在對象創建時,我們可能需要做一些初始化工作,可以使用初始化代碼塊來完成,初始化代碼塊使用init關鍵字來完成,Init 函數在創建對象的時候會自動執行;
- 例如,我們希望對象在創建時,如果年齡不足18歲,那么就設定為18歲
- 這樣在創建對象的時候,就會在創建的時候自動執行初始化代碼塊里面的代碼了
fun main(args: Array<String>) {var stu = Student("小明", 9)}class Student (var name: String, var age: Int) {// 可以定義多個init,執行順序為從上往下依次執行init {println("我是初始化操作")if (age < 18) age = 18println(age)println("初始化操作結束")}init {}
}
4)類的成員函數
- 如果函數中的變量存在歧義,那么優先使用作用于最近的一個,比如函數形參的 name 作用域更近,那么這里的 name 拿到的一個是形參 name,而不是類的成員屬性 name
- 如果我們要獲取的是類中的成員屬性,需要使用 this 關鍵字來表示當前類
- 默認情況下,如果作用域不沖突,使用類中屬性 this 可以省略
fun main(args: Array<String>) {var stu = Student("小明", 19)stu.hello()
}class Student (var name: String, var age: Int) {fun hello() {println("大家好啊")}
}// 默認變量指代的就是離它最近的
class Student (var name: String, var age: Int) {fun hello(name: String) {println("大家好啊,我叫$name") // 指代的是hello中的參數name// 使用 this 關鍵字表示當前對象,這樣就可以指定這里是類中this中的name 屬性了println("大家好啊,我叫${this.name}") // 指代的是類中屬性name}
}
在類中,同樣可以定義多個同名但是不同參數的函數實現重載
class Student(var name: String, var age: Int) {fun hello() = println("大家好,我叫 ${this.name},今年${age}歲")fun hello(gender: String) = println("大家好,我叫 ${this.name},今年 ${age} 歲,性別 ${gender}")
}
5) 再談基本類型
- Kotlin 中萬物皆對象,所有變量存儲的都是對象的引用
fun main(args: Array<String>) {val a: Int = 10 // Int類型的對象,值為10,而a持有的是對這個Int對象的引用val b: Double = a.toDouble()
}
fun main(args: Array<String>) {val a: Int = 10 // Int類型的對象,值為10,而a持有的是對這個Int對象的引用val b: Int = 5val c: Double = b / a.toDouble() // 結果為0.5
}fun main(args: Array<String>) {val str: String = "10"str.length()str.toInt()
}
a、空值和空類型
- 所有的變量除了引用一個具體的值以外,還有一種特殊的值可以使用,就是 null,它代表空值,即不引用任何對象
- 所有的類型默認都是非空類型,非空類型的變量是不允許被賦值為 null,這直接在編譯階段就避免了其他語言中經常存在的空指針問題
fun main(args: Array<String>) {val stu: Student = null //報錯
}
- 希望某個變量在初始化情況下使用 null,而不是去引用某個具體的對象,將變量的類型修改為可空類型,只需要再類型名的后面添加一個 ? 即可
val stu: Student? = null // 正確,加了?號之后就可以為空了,不代表任何對象
6)修飾符
- private、internal、public
7)封裝
class Student(private var name: String, private var age: Int) {fun getName(): String = namefun getAge(): Int = agefun setName(name: String) {if (name.contains("剛")) returnthis.name = name}
}
8)繼承
- Kotlin 中類是 終態的(不能被任何類繼承),要使類可繼承,需要用關鍵字 open 標記需要被繼承的類
open class Student { // 可以被繼承,可作為父類}class ArtStudent: Student() { // 以調用主構造函數的形式進行聲明,這個類就是Student的子類}
- 當一個類繼承另一個類時,屬性會被繼承,可以直接訪問父類中定義的屬性,除非父類中將屬性的訪問權限修改為 private,那么子類將無法訪問
open class Student { // 可以被繼承,可作為父類var name: String = "小明"fun hello() = println("大家好,我叫 $name")
}class ArtStudent: Student() { // 以調用主構造函數的形式進行聲明,這個類就是Student的子類fun test() {name // 可以直接訪問父類中的屬性hello() // 可以直接訪問父類中的方法}
}
9)屬性的覆蓋——多態
- 子類重寫父類定義的內容
- 有些時候,我們可以子類繼承父類的某些屬性,,但是我們可能希望去修改這些屬性的默認實現,可以使用 override 關鍵字來表示對一個屬性的重寫(覆蓋)
fun main() {var student = ArtStudent()student.hello()}open class Student { // 可以被繼承,可作為父類open fun hello() = println("我會打招呼")
}class ArtStudent: Student() { // 以調用主構造函數的形式進行聲明,這個類就是Student的子類fun draw() = println("我會畫畫")override fun hello() {// 在子類中編寫一個同名函數,并添加override關鍵字,就可以在子類中進行覆蓋了,然后編寫自己的實現println("我會畫畫")super.hello() // 可以執行父類的}
}class MusicStudent: Student() {override fun hello() = println("我會唱歌")
}
10)接口
- 定義一些所具備的功能
interface A {val x: String // 接口中所有屬性默認都是abstract的(所以可省略abstract關鍵字)fun sleep() // 接口中所有函數默認都是abstract的(所以可省略abstract關鍵字)
}interface B {fun game()
}// 用類去實現接口中的功能
// Student 實現了A和B接口,證明同時具有了A和B中的功能
class Student: A, B { // 接口的實現和類的繼承一樣,直接寫到后面,多個接口用逗號隔開override val x: String = "測試" // 跟抽象類一樣,接口中的內容是必須要實現的override fun game() = println("玩游戲")override fun sleep() = println("睡覺")
}
10、數組的創建與使用
- 存放一組相同類型的數據
- 在kotlin中,數組是Array類型的對象
- 在 Kotlin 中創建數組有兩種創建方式:1)官方預設工具函數:arrayOf()、arrayOfNulls() 以及 emptyArray()
- 使用類 Array 構造函數創建
val array: Array<Int> = arrayOf(7, 3, 9, 1, 6) // 直接在arrayOf函數中添加每個元素
-
注意:數組在創建完成后,數組容量和元素類型是固定不變的,后續無法進行修改
-
數組元素的訪問和修改
val array: Array<Int> = arrayOf(7, 3, 9, 1, 6) // 直接在arrayOf函數中添加每個元素
println(array[0])
array[0] = 2val array: Array<Int> = arrayOf(7, 3, 9, 1, 6) // 直接在arrayOf函數中添加每個元素
for (i in 0 until array.size) { // 方式1println(array[i])
}for (element in array) { // 方式2println(element)
}
- 數組中的操作
val array1: Array<Int> = arrayOf(1, 2, 3, 4, 5)
val array2: Array<Int> = arrayOf(1, 2, 3, 4, 5)
val array3 = array1println(array1 == array2) // 結果為false,比較是否是兩個同一個對象
println(array1 == array3) // 結果為true,因為比較的是兩個相同的對象// 比較兩個數組中的內容是否相同
println(array1.contentEquals(array2)) // 結果為true,兩者內容相同
11、集合類
1)數組局限性
- 長度是固定的,無法擴展 ;
- 無法做到在數組中像列表那樣進行插入和刪除元素;
2)集合的分類
- List:有序的集合,通過索引訪問元素,可以包含重復元素
- Set:不包含重復元素的集合,一般情況下不維護元素順序
- Map:是一組鍵值對,其中每個鍵不可重復存在,每個鍵都映射到恰好一個值(值可以重復存在)
- 所有集合類都是繼承自 Collection 接口(Map 除外)
3)集合簡介
- List:可以自由地在某個位置插入或刪除一個元素,列表的長度也會動態發生變化
// 創建一個 listval list: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5) // 創建可變集合// 支持所有數組的操作list[0] = 10println(list) // 格式化地打印println(list.get(1)) // 取數據list.add(9) // 在末尾添加一個新元素list.add(1, 10) // 在下標為1處,添加元素10,可插入范圍只能是[0, size]這個閉區間內
- Set 集合
// 創建一個Set集合
val set: Set<String> = mutableSetOf("AA", "BB", "BB", "CC")
println(set) // 因為set中不允許出現重復元素,結果為 [AA, BB, CC]
- Map
// 創建一個 Map
val map: MutableMap<Int, Student> = mutableMapOf(10001 to Student("小明", 18),10002 to Student("小紅", 17),10003 ti Student("小剛", 16)
)
val student: Student? = map[10001] // 使用[]運算符通過Key查找value
val student1: Student? = map[10001] // 得到小明這個對象
val student2: Student? = map[10005] // Map 中根本沒有鍵為10005的鍵值對,所以得到結果為null
map.contains(1) // 判斷是否包含指定Key
map.containKey(1) // 同上
10001 in map // 同上map.containsValue(Student("小明", 18)) // 判斷是否包含Value
val keys: MutableSet<Int> = map.keys //以Set形式存儲的[10001, 10002, 10003]
val value: Collection<Student> = map.values