Kotlin基礎一

稀飯_發表於2018-06-10

內容

  • 函式、變數、類、屬性以及列舉
  •  Kotlin 中的控制結構 
  • 智慧轉換

一  函式宣告

fun max(a: Int, b: Int): Int {

    return if (a > b) a else b
}複製程式碼

      函式的宣告以關鍵字 fun 開始,函式名稱緊隨其後:這個例子中函式名稱是 max ,接下來是括號括起來的引數列表。引數列表的後面跟著返回型別,他們之間用冒號隔開。假如沒有返回值可以直接不寫或者寫成Unit型別。

注意:這裡return後邊程式碼是表示式而不是語句,表示式有返回值,語句沒有返回值。而再Kotlin中基本,除了迴圈( for, do do/while )以外大多數控制結構都是表示式。

上邊函式還可以這樣寫:

fun max(a: Int, b: Int): Int = if (a > b) a else b複製程式碼

如果函式體寫在花括號中,我們說這個函式有程式碼塊體。如果它直接返回了個表示式,它就有表示式體

還可以這樣寫:

fun max(a: Int, b: Int) = if (a > b) a else b複製程式碼

因為Kotlin有型別自動推導特性。

注意:只有表示式體函式的返回型別可以省略。對於有返回值的程式碼塊體函式, 必須顯式地寫出返回型別和 return 語句。

二 常量和變數

在 Kotlin中以關鍵字開始,然後是變數名稱, 最後可以加上型別(不加也可以)。宣告變數的關鍵字有兩個

  •  val (使用 val 宣告的變數不能在初始化之 後再次賦值。它對應的是 Java final 量。) 
  •  var (這種變數的值可以被改變。這種宣告對 應的是普通(非 final )的 Java 量。)

如下:

fun ddd() {
    //隱式宣告區域性常量,型別自動推導
    val a = 1
    //顯示宣告區域性變數
    var b: Int = 2
    //如果不能提供可以賦給這個常量的值的資訊,編譯器就無法推斷出它的型別,並且val只有一次賦值機會
    val c: String
    c = "Kotlin就是厲害"
}複製程式碼

注意 val 引用自身是不可變的,但是它指向的物件可能是可變的。如下程式碼完全有效

val array= arrayListOf<String>("1","2","3")
array.add("4")複製程式碼

不可變物件和可變物件我們之後再討論。

注意:編譯器只會根據初始化器來推斷變數的型別,在決定型別的時候不會考慮 後續的賦值操作。如下錯誤的寫法:

var b: Int = 2
b = "型別錯誤"複製程式碼

三 類

 java中的類:

public class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}複製程式碼

使用Kotlin就變成了:

class Person(val name: String)複製程式碼

注意:從 Java otlin 的轉換過程中 public 修飾符消失了 。在 Kotlin 中, public 是預設的可見性,所以你能省略它。

四 屬性

4.1 屬性宣告和使用

       在類中宣告一個屬性和宣告一個變數一樣:使用val和var關鍵字。宣告成val的屬性是隻讀的,而var屬性是可變的。當你宣告屬性的時候,你就宣告瞭對應的get和set方法(只讀屬性有一個get,而可寫屬性既有get也有set)如:

class Person {
    var name: String = "張三"
    val isMan: Boolean = false
}
複製程式碼

當你使用這個類的屬性時候,內部其實是呼叫的對應的get和set方法,而是未呈現出來

var p = Person()
//設定值,內部其實是呼叫了set,只是未呈現
p.name = "張三"
//獲取值,內部其實是呼叫了get,只是未呈現
Log.e("rrrrr",p.name)複製程式碼

如果我們去呈現他的get和set方法的就像這樣:

class Person {
    var name: String = "張三"
    get(){
        return field
    }
    set(value) {
        field = value
    }
    
    val isMan: Boolean = false
        get(){
            return field
        }

}複製程式碼

注意:需要解釋的是這個field ,你可以把field認為就是name,也可以把field認為是isMan,它的出現就是為了解決死迴圈,因為預設使用屬性,就是呼叫屬性的get方法。

4.2 自定義get和set方法

如建立一個長方形類,裡邊有一個欄位,是判斷長方形是否是正方形的標記,我們可以這樣寫:

class Rect(var w :Int ,var h:Int) {
    val isSQ :Boolean
    get() {
        return w==h
    }
}複製程式碼

呼叫:

var rect = Rect(10,10)
Log.e("rrrrrrr","${rect.isSQ}")複製程式碼

Log如下:

rrrrrrr: true                                                                                

4.3 修改屬性的可見性

我們可以在自定義的get或者set方法前邊加上可見修飾符去修改屬性的可見性,訪問器的可見性預設與屬性的可見性相同。

五 列舉

      Kotlin中使用了兩個關鍵字去宣告列舉,enum 和 class, enum是一個所謂的軟關鍵字:只有當它出現在class前面時才有特殊的意義,在其他地方可以把它當作普通的名稱使用。

enum class Colors() {
    //建立列舉物件
    Red(),Blue(),Black();

}複製程式碼

六 控制語句

6.1 when

when好比java中的switch,比switch強大之處,它也是一個表示式,有返回值,不僅可以傳遞常量,還可以傳遞物件。通過上邊列舉去選擇性返回一個數字,程式碼如下:

6.1.1傳遞常量

private fun select(color: Colors): Int {
    return when (color) {
        Colors.Blue->0 
        Colors.Black -> 1
        Colors.Red -> 2
    }
}複製程式碼

呼叫這個方法,傳遞的引數不同,獲取到的返回值也是不同的。上邊程式碼還可以寫成這樣:

fun select(color: Colors) = when (color) {Colors.Blue->0 ;Colors.Black -> 1 ;Colors.Red -> 2 }複製程式碼

6.1.2 傳遞物件

假設我們有這樣一個需求,用程式碼建立一個調色盤,傳遞一個倆個顏色的set集合物件,返回一個他們的綜合色,程式碼如下:

fun palette(color1: Color, color2: Color): String {
    return when (setOf(color1, color2)) {
        setOf(Color.Red, Color.Black) -> "藍色"
        setOf(Color.Red, Color.Blue) -> "綠色"
        else -> "未知顏色"
    }

}複製程式碼

注意:

set集合這樣寫他們是相等的:

val set1 = setOf("1","22")
val set2 = setOf("22","1")
複製程式碼

但是這樣寫他們就是不相等

val set1 = HashSet<String>()
set1.add("1")
set1.add("22")
val set2 = HashSet<String>()
set1.add("22")
set1.add("1")複製程式碼

在java中更是需要自己去迴圈比較是否相等。


而list集合不管怎麼樣去建立都是相等的:

var arr1 = ArrayList<String>()
arr1.add("11")
arr1.add("22")
var arr2 = ArrayList<String>()
arr2.add("11")
arr2.add("22")

var arr3  = listOf("11","22")
var arr4  = listOf("11","22")複製程式碼

在java中用equals方法判斷裡邊值是否相等

關於更多的集合的比較在後邊在去詳細說明,這裡先記下有這個情況!!!

6.2 if

6.2.1基本用法

上文已經簡單的使用了,if的基本用法:

fun max(a: Int, b: Int) = if (a > b) a else b複製程式碼

這個表示式體和三元運算子長的很像,因為在Kotlin中if是表示式有返回值 ,所以在Kotlin中沒有三元運算子的語法。

     在java中型別轉換需使用instanceOf , 之後再去向下轉型。在kotlin中使用關鍵字is 判斷後,型別會自定轉換成你要轉換的型別方法。

這裡我們去建立一個父親介面,還有兩個兒子類有各種獨有的方法:

interface Father

class Son1:Father{ fun  son1Method(){} }

class Son2:Father{ fun  son2Method(){} }
複製程式碼

判斷是哪個兒子的方法:

fun who(aaa: Father) {
  if (aaa is Son1){
      aaa.son1Method()//這裡判斷是兒子1,只能呼叫兒子1的方法
  }else if (aaa is Son2){
      aaa.son2Method()//這裡是兒子2,只能呼叫兒子2的方法
  }
}複製程式碼

 如果想要顯示的轉換型別就需要使用 as關鍵字。

6.2.2 if和when之間轉換

上邊程式碼判斷是哪個兒子的方法,用when重構程式碼如下:

fun who(aaa: Father) {

    when (aaa){
         is Son1->aaa.son1Method()
         is Son2->aaa.son2Method()
    }

}複製程式碼

這裡更加說明when的強大之處,可以傳遞常量,物件,甚至是型別判斷

6.3 while

Kotlin並沒有給這些簡單的迴圈帶來任何新東西,和java一樣,不作為探討內容。

6.4 for

6.4.1基礎

for迴圈僅以唯一一種形式存在,和Java的for-each迴圈一致。Kotlin使用了區間的概念,區間本質上就是兩個值之間的間隔,這兩個值通常是數字:一個起始值,一個結束值,且起始值必須小於結束值。使用..運算子來表示區間:val oneToTen = 1..10,預設總是前後都是閉合區間
for (a in 1..100){
    
}複製程式碼

起始值大於結束值用downTo:

for (a in 100 downTo 1){
  
}複製程式碼

每隔兩步一迴圈

for (a in 1..100 step 2 ){

}

for (a in 100 downTo 1 step 2){

}複製程式碼

step傳遞的是絕對值,和正序倒序無關,它會自動判斷是每加兩步還是每減兩步

如果迴圈區間想寫成前閉後開,你可以這樣:

for (a in 1 until 100){
}複製程式碼

小結:for迴圈必須使用關鍵字in ,至於區間可以在 .. 或者downTo 或者until之間最少選擇一個,step表示步長,和正負無關。

6.4.2迴圈map

迴圈map還是和java中有區別的,在java中迴圈map需要去通過鍵獲取值,而在kotlin中你可以一次全部迴圈處理,程式碼可以這樣寫:

val map = TreeMap<String,String>()
 map.put("1","1.1")
 for ((key,value) in map) {
     Log.e("rrrr","key${key}===value${value}")
 }複製程式碼

這使你更加容易去取到map中的值。

6.4.3迴圈arraylist:

val arr = arrayListOf("1","2")
//正常迴圈和java並無異樣
 for (value in arr){  
     Log.e("rrr","value${value}")
 }
  //使用withIndex 迴圈,是迴圈帶有下邊的list集合
 for ((index ,value) in arr.withIndex()){
     Log.e("rrr","value${value}index${index}")
 }複製程式碼

6.4.4 in關鍵字能用到哪些控制結構中

上邊迴圈for中使用了in。同時在if中也能用in使用in運算子來檢查一個值是否在區間中,或者它的逆運算,!n,來檢查這個值是否不在區間中。

val arr = arrayListOf("1","2")
if ("1" !in arr){
}複製程式碼

而且在when中也能使用in,程式碼和使用is是一樣的。

小結:

  • 方法宣告的結構,以及表示式體和程式碼塊體。
  • 常量和比變數的宣告,陣列不變,陣列裡內容可變
  • 型別自動推導的便捷使用。
  • 類的宣告,以及關鍵字class 
  • 屬性的宣告以及重寫get和set方法
  • 列舉的宣告格式,軟關鍵字menu
  • when控制結構,可以傳遞常量物件,甚至可以使用is或者in關鍵字
  • if控制結構,使用關鍵字is ,in, .. , downTo ,step ,until
  • for控制結果,使用關鍵字 in, .. , downTo ,step ,until,迴圈map和迴圈帶下表的arraylist集合



相關文章