Kotlin的解析(上)

春來江水綠如藍發表於2018-11-14

前言

1. Kotlin的概述:

1.1 kotlin是什麼
(1)Kotlin是由JetBrains建立的基於JVM的程式語言
(2)在技術層面上,JAVA和Kotlin是同一級別的,都是以Java Byte Code形式執行在虛擬機器上
1.2kotlin相對於Java有什麼優勢
(1)更容易學習:Kotlin是一門包含很多函數語言程式設計思想的物件導向的程式語言
(2)輕量級:相比於其他的語言,Kotlin函式庫更小,由於Android存在65K方法數限制,使得這一點比較重要
(3)高度互操作性:Kotlin可以和其他Java庫友好且簡單的進行互相操作
(4)非常友好的整合Android Studio 以Gradle,Kotlin又一個專門用於Android Studio的外掛,以及另一個專門用於Gradle的外掛。推出的AS3.0+已經整合了Kotlin
(5)Kotlin還有很多語法層面的特性,如資料模型、空指標安全、擴充套件函式等
1.3 kotlin能做什麼
(1)服務端開發
(2)以JavaScrip方式執行
(3)開發Android App

2.Kotlin基礎知識

2.1基礎語法

2.1.1 定義變數:

   絕大數程式語言都有常量和變數,Kotlin和同源的Java類似,儘管沒有常量語法,但可以使用final關鍵字定一個不可以修改的變數複製程式碼
Java程式碼
int n=30;
int ok;
final int m =20;
ok =123;
m=10;
複製程式碼
Kotlin程式碼
var n :Int =30var ok:Int val m :Int =20 m=10 //編譯出錯,因為m是常量複製程式碼

不同點

(1)位置不同

(2)變數和常量需要關鍵字:在Kotlin中,定義變數需要var,定義常量需要val開頭

(3)資料型別首字母:在kotlin中,資料型別都以大寫字母開頭

(4)如果在定義變數時未進行初始化,就必須要制定資料型別,如果在定義變數時進行了初始化,可以不指定資料的型別,Kotlin編譯器會自動根據等號右側的值推倒資料的型別

2.1.2 定義函式

函式定義如下幾個部分:

(1)函式頭,包括函式名和識別函式的關鍵字,如fun、function等

(2)引數,包括引數名和引數型別

(3)返回值

Kotlin 程式碼
fun add (m: Int ,n:Int):int{return m+n
}fun process(m: Int):Unit //也可以省略{println(m*m)
}複製程式碼

2.1 .3 註解

(1)但行註解 //(2塊註解//(3)巢狀註解/*//*/ 新增的Java中是不支援的

2.2 基礎資料型別

2.2.1 數值型別

資料型別 佔用位元組數
Double 8
Float 4
Long 8
Int 4
Short 2
Byte 1
Kotlin程式碼
var m =29val n :Byte=10m=n  //編譯錯誤,無法將Byte隱式轉換為Intvar x:Long =20 //可以將Int型別的值隱式轉為Longval value:Short=20m=value //編譯錯誤,無法將short隱失轉換為Int複製程式碼

如果我非要轉換呢?莫急Kotlin提供了一系列的方法使用來進行型別之間的轉換:

toByte()   toShort() ... toChar()複製程式碼

Kotlin與Java一樣提供了一些特殊的表示方法,表示Long、Float以及十六進位制和二進位制(八進位制目前還不支援)(1)表示Long/Float型別的值,在數字後面加上L/F或者l/f(2)表示十六進位制,在數之前加0x(3)表示二進位制,數值前面加0b(4)如果數值很大,還可以123_3454_567這樣表示

2.2.2 字元型別

在Kotlin語言中,字元型別用Char描述,不過和JAVA不同的是,在Kotlin中,字元不能直接看作數字

Java程式碼
void check(char c){if(c == 97){//可以編譯通過
}複製程式碼
Kotlin程式碼
fun check(c: Char){if(c == 97){//會產生編譯錯誤
}
}複製程式碼

2.2.3 布林值

Kotlin語言中的布林型別用Boolean描述,該型別有兩個值:true 和false

2.2.4 陣列

//使用arrayOf 函式定義可以儲存人意的陣列val arr1 = arrayOf(1,2,3,'a')print(arr1[1])arr1[2]='b'//使用arrayOfNulls 函式定義陣列var arr2 = arrayOfNulls<
Int>
(10)val arr3 = Array(10,{i ->
(i*i).toString()
}println(arr3[3])複製程式碼

2.2.5 字元竄

//第一類字串(與Java類似)var s1 = "hello \nword"println(s1)//第2類字元竄,保留原始格式var s3=""" hello                           word            hehhe!"""複製程式碼

字串模版

val i=10val s1 = "I = $I"println(s1) val s2 = "abd"val str = "$s2 的長度是 ${s2.length
}
"
println(str)複製程式碼

2.3 控制流

2.3.1 條件語句

Kotlin 程式碼(傳統的if用法)

var a = 20var b =30var max :Intvar min: Intif(a>
b){max = b
}if(a>
b){min=a
}else{min=b
}複製程式碼

Kotlin 程式碼(將if語句作為表示式使用)

var a=20var b=30val max =if(a>
b)a else bprintln(max)//if. else 後面是一個程式碼塊,最後一個表示式將作為返回值val min = if(a>
b){println(a)a
}else{println(b)b
}複製程式碼

2.3.2 when 語句(代替了java的switch語句,功能簡直是逆天)

(1)標準的when的用法

var x=1when(x){1 ->
{println("x == 1")
}2->
{println("x==2")
}else ->
{println("輸出:x")
}
}複製程式碼

(2)when作為表示式使用

var x =1var m = when(x){1 ,3,4->
{
//如果多個分支執行的結果一樣,可以在一個分支用(,)分隔多個條件println("x ==1")10
}2 ->
{println("x==2")20
} else ->
{println("x")40
}
}println(m)複製程式碼

(3)使用in關鍵字

var n = 25when(n){in 1..10 ->
println("輸初")!in 30 .. 60 ->
print("非30-60範圍")else ->
println("條件未知")複製程式碼

(4)分支條件還可以式函式

fun getValue(x:Int):Int{return x
}var n =4when(n){getValue(2)->
println("2")getValue(4)->
println(4)else ->
println("沒有滿足條件!")複製程式碼

2.3.3 for 迴圈

列舉陣列中所有的元素

var arr = intArrayof(2,4,5,7,8)for(item : Int in arr){println(item)
}for (i in arr.indices){println("arr[$i] = " +arr[i])
}複製程式碼

2.3.4 while 迴圈

和Java裡面式一樣的,就不多說了,自己可以看一下,沒啥變化的

3. 類和介面

與Java一樣,在Kotlin中,類的宣告也使用class,如果只是宣告一個空的類的話,Kotlin和Java沒有任何的區別,不過要是定義其他的成員,差別還是很大3.1 構造器

3.1.1 主構造器

  在Kotlin中,類允許定義一個主的構造器(primary constructor)和若干個第二構造器(secondary constructor),主構造器是類頭的一部分,緊跟在類名的後面,構造器引數是可選的kotlin 程式碼

class Persion constructor(firstName:String){
}//如果主構造器沒有任何的註解或者修飾器,constructor關鍵字可以省略class Persion(firstName:String){
}複製程式碼

  目前大家可能有疑惑,程式碼重只看的見定義主構造器,那麼應該在哪裡實現主構造器呢?其實,如果是主構造器的話,需要在init塊中進行初始化

class Persion (firstName:String){var name = firstNameinit{println(firstName);

}
}//要注意的,主構造器的引數不僅可以用於在init塊中,還可以用於對類屬性的初始化複製程式碼

3.1.2 第二構造器

  (1)Kotlin類除了可以宣告一個主構造器,還可以宣告若干個第二構造器,第二構造器需要在類中宣告,前面必須加上constructor關鍵字Kotlin 程式碼

class Persion {constructor(parent:Persion){println(parent)
}
}複製程式碼

  (2)如若類中宣告瞭主構造器,那麼所有的第二構造器都需要在宣告後面呼叫主構造器,或者通過另外一個第二構造器間接的呼叫第二構造器Kotlin 程式碼

class Demo(var url : String){//主構造器實現部分init{println("主構造器,嘻嘻!無知的人類")
}//第二構造器(通過this直接呼叫了主構造器)constructor(value:Int):this("https://linghit666.doubi.com"){println(value)
}//通過this直接呼叫了主函式constructor(des:String,url:String):this("{"+url+"
}"
){println(des+";
;
;
;
"
+url)
}//通過第二構造器間接的呼叫主構造器constructor():this(20){println("https://www.doubi.com")
}
}複製程式碼

注意:在主構造器引數重可以使用var和val,但第二構造器中不能使用var和val,意思就是第二構造器的引數都是直讀的,不能在構造器的內部改變引數值

3.1.3 Kotlin 中的Singleton模式

Kotlin 程式碼(Singleton 模式)

class Singleton private constructor() { 
private object mHolder {
var INSTANCE = Singleton()
} companion object {
fun getInstance(): Singleton {
return mHolder.INSTANCE
}
}
}//是不是感覺大吃一驚,相對於Java的單例模式,是不是很懵逼,之所以Kotlin方式不同,主要因為Kotlin類不支援靜態方法和成員,由於kotlin支援全域性函式和變數,因此可以直接使用全域性函式和變數來代替靜態方法和靜態成員變數複製程式碼

3.1.4 Kotlin 函式中預設引數

  現在的很多語言都支援預設引數,例如js、dart、go等,但是遺憾的是Java並不支援,是不是很氣,但是值得慶幸的是Kotlin卻是支援預設引數

class Persion(val name:String="Bill",var value :Float = 20.4f,sex :Int) { 
//其實這個是Kotlin的一個語法糖,想知道原理的可以反編一下,檢視一下位元組碼,應該就會懂了
}複製程式碼

3.2 類成員

  Kotlin 中屬性的語法

var/val [:][=<
property_initalizer>
][][]

3.2.1 屬性的getter和setter 形式

  由於Kotlin從語法上支援屬性,因此並不需要為每一個屬性單獨定義getter和setter方法Kotlin 程式碼

class Persion { 
private var name: String = "sdfsfd" fun getName(): String {
return name
} var value: Int = 0 get() = field set(value) {
field = value Log.i("tag","數值: " +";;;;" +value)
}
}複製程式碼

3.3 類的繼承

3.3.1 修飾符

private :僅僅在類的內部可以訪問protected:類似上面的,但是可以在子類中也可以訪問internal:任何在模組內部的類都可以訪問public:任何的類都可以訪問複製程式碼

示例:

open class Outer { 
private val a = 1 protected open val b = 2 internal val c = 3 val d = 4 //預設的是public protected class Nested {
public val e: Int = 5
}
}class SubClass : Outer() {
//a不能訪問,b、c、d、Nested().e都可以訪問 override val b: Int = 10 //重寫父類的常量b init {
b c d Nested().e
}
}複製程式碼

3.3.2 類的繼承

  與Java不同,Kotlin類的繼承需要使用(:)冒號,而JAVA你懂得,注意,冒號後面需要呼叫父類的構造器,與JAVA一樣,都是單繼承,Kotlin預設時class是final的,也就是說,預設的時候不允許繼承,需要顯示的使用open

open class Parent {//使用open宣告,才能允許其他類繼承open val name :String ="know"    protected var sex =1;
open protected fun getYcSex():Int{
return sex
}
}class Child :Parent(){override var name:String ="wukong" override fun getYcSex(): Int {
return super.getYcSex()
}
}//如果在子類中重寫方法,就需要在父類相應的方法前面加open,而且要在子類的方法前面加override//如果想阻止子類的方法被重寫,就要在override前面加final//屬性重寫與方法類似,被重寫的屬性前面需使用open宣告,子類的屬性前加override,注意的是,val屬性可以被重寫成var的,反之不行複製程式碼

3.4 介面

  Kotlin中的介面與Java類似,使用interface關鍵字宣告,一個類可以實現多個介面,而且介面中的屬性以及方法都是open的

3.4.1介面的示例

interface Extend{ 
fun process() fun getYcName():String{
//允許介面包含預設的方法體,有方法體的,不要求一定重寫 return "nihao"
}
}class Child :Parent(),Extend{
override fun process() {

} override fun getYcName(): String {
// 可以不重寫 return super.getYcName()
} override fun getYcSex(): Int {
return super.getYcSex()
}
}複製程式碼

3.4.2抽象類

抽象方法不需要使用open宣告,因為抽象方法類本身都可以繼承

abstract class ChouXiang :Extend{ 
abstract fun hellow()
}class Persion :ChouXiang() {
override fun hellow() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
} override fun process() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}複製程式碼
總結

截止目前的話Kotlin中大概的基礎知識,差不多都示例講解了一下,基本的一些東西都可以看懂知道了,希望對你想了解kotlin有些幫助

來源:https://juejin.im/post/5beaf5f86fb9a04a0c2dfd0b

相關文章