1. 程式人生 > >kotlin基礎筆記之類、介面、函式和基本語法

kotlin基礎筆記之類、介面、函式和基本語法

純粹是個人學習總結,如有不對的地方請吐槽。

kotlin包概念

其實kotlin類和包沒有直接的聯絡,包名可以和檔案存放的路徑不一致。
比如檔案的存放地址是:com.xxx.yyy,包名可以是 package com.yyy.xxx

Imports關鍵字

在java中是用於匯入的
在kotlin中也是匯入作用的,它可以匯入類,包,變數等等,匯入方式和java也是一樣的
如果包有衝突可以用以下方式重新命名
import foo.Bar // Bar 可以使用
import bar.Bar as bBar // bBar 代表 'bar.Bar'
在這裡as關鍵字的作用就是將bar.Bar變成bBar來代表

定義一個kotlin類

//普通類定義
package com.yyy.xxx
class A{
    fun a(){
      println("這是一個無參無返回值的方法")
    }
  }

//有繼承關係的類
 package com.yyy.xxx
  class KotlinActivity : AppCompatActivity(){
  //實現父類的方法
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_kotlin)
    }
}
建立Kotlin類例項
val a = A()
跳轉到KotlinActivity:
startActivity(Intent(this, MainActivity::class.java))

函式定義

只有一個表示式的函式定義

fun sum(a: Int, b: Int):Int = a + b  也可以 fun sum(a: Int, b: Int) = a + b
//後面的定義就是編譯器可以推匯出返回值型別,就可以不寫返回值型別

沒有返回值的函式定義

fun sum():Unit{ println("無參無返回值函式") }也可以fun sum(){ println("無參無返回值函式") }

預設引數函式定義

fun sum(b: Int, off: Int = 0, stepNum: Int = 1) {
}
呼叫方式:sum(10)//沒有傳遞的引數就等於預設值,這樣可以減少過載

命名引數函式定義

fun sum(str: String, isMax: Boolean = true,a: Char = ' ') {
}
呼叫方式:
1.預設引數呼叫sum(str)
2.命名引數呼叫sum(str,isMax=true,a='a')或者sum(str,a='a')
這種方式呼叫,程式碼可讀性更強,更加靈活,沒有傳遞的引數就是預設值
注意:命名引數語法不能夠被用於呼叫Java函式中,因為Java的位元組碼不能確保方法引數命名的不變性

中綴符號

//給 Int 定義一個擴充套件方法
infix fun Int.shl(x: Int): Int {
}
呼叫方式:1 shl 2 或者 1.shl(2)
注意:只能有一個引數

函式擴充套件
在不繼承類的情況下增加方法叫Extensions(擴充套件函式),我們需要在函式前加一個接收者型別作為字首如給MutableList<Int> 新增一個 swap 函式:

fun MutableList<Int>.swap(x: Int, y: Int) {
    val tmp = this[x] // this 對應 list
    this[x] = this[y]
    this[y] = tmp
}
呼叫方式:
val l = mutableListOf(1, 2, 3)
l.swap(0, 2)
在swap() 函式中this持有的值是l

變長引數函式定義

fun <T> asList(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts)
        result.add(t)
    return result
}
呼叫方式:asList(1,2,3)或者asList(1,2,3,4,5),引數長度可隨意變換

只有一個引數可以被標註為 vararg,如果vararg並不是列表中的最後一個引數,那麼後面的引數需要通過命名引數語法進行傳值,再或者如果這個引數是函式型別,就需要通過lambda法則.
如果引數中有一個是陣列怎麼傳遞?

val a = array(1, 2, 3)
val list = asList(-1, 0, *a, 4)
a變數在傳遞時一定要加前面的*號

區域性函式定義
在一個函式裡面包含一個函式

fun dfs(graph: Graph) {
    fun dfs(current: Vertex, visited: Set<Vertex>) {
        if (!visited.add(current)) return
        for (v in current.neighbors)
            dfs(v, visited)
    }
    dfs(graph.vertices[0], HashSet())
}
介面定義
interface MyInterface {
    fun bar()
    fun foo() {
        //函式體是可選的
    }
}
介面實現
class Child : MyInterface {
    fun bar () {
        //函式體
    }
}
和java一樣一個類可以實現一個或多個介面

基本語法

變數宣告
var宣告可變變數 
var i = 1
i = 2
println("i:"+i)
輸出結果:i:2

val宣告只讀變數
val j = 1
val k:Int//只宣告沒有賦值
j=2//編譯會報錯
k = 3//第一次賦值,編譯通過
val就相當於java的final
if else

if else 和java的用法基本一致,kotlin沒有三目運算子那怎麼實現呢,就是用if else如:

var j = if(number>3) 0 else 1
when

when用法相當於java中的switch,但是比switch強大
when的判斷條件可以重複,如果重複了,就按照最先原則匹配。

while do ..while 迴圈

他們的用法和java中完全相同

字串
賦值var str = "abc"
拼接:str+="def"//拼接後abcdef

模板字串
println("${str}123");//列印abcdef123
運算:
var a=1
var b = 2
println("${str}123${a+b}");//列印abcdef1233
範圍表示式
建立範圍需要...操作符如:var i=1..10//i中包含1,2,3,4,5,6,7,8,9,10
建立降序範圍:var i = 3 downTo 1//i中包含3,2,1
步長範圍建立:var i = 1..10 step 5//i中包含1,6 降序也是一樣的
in操作符
判斷是否在某個範圍
if (x in 1..10)
print("x:${x}是在1-10之間")
判斷不在某個範圍
if (x !in 1..10)
print("x:${x}不在1-10之間")