[AS3.6.1]Kotlin學習筆記1

前言

久違的寫博客了!這段時間也算是加班完了累又不想學習,然後擱那瘋狂的摸魚。一直想開始記錄學習kotlin都沒時間,這次算是閒下來給自己個目標把kotlin學完吧!

基本使用

聲明變量

kotlin和java一樣都是有變量的,但是聲明的方式有挺大的區別

	//java 聲明變量
	int x;	//默認值 0
	String name;	//默認值null
	final int finalX = 5;
	final String phone = "17712345678"
	
	//kotlin
	var x:Int = 0	//必須設置默認值
	var name:String = "張三"
	val finalX:Int = 5
	val phone = "17712345678"

上面我們能看到區別,kotlin沒有默認值,聲明的時候必須設置值,統一用varval作爲聲明 用:xxx來說明參數的類型,甚至可以不聲明什麼對象讓系統自動識別出來對象的類型。還有就是int變成了Int 部分相應的字段變化如下

java kotlin
byte Byte
char Char
short Short
long Long
float Float
double Double

引用鏈接

var number: Int = 1 // 👈還有 Double Float Long Short Byte 都類似
var c: Char = ‘c’
var b: Boolean = true
var array: IntArray = intArrayOf(1, 2) // 👈類似的還有 FloatArray DoubleArray CharArray 等,intArrayOf 是 Kotlin 的 built-in 函數
var str: String = “string”

我們發現基本都是使用了對象的形式,雖然原來的java也有但是我們一般都是用java自帶的,這邊要注意下使用對象形式的字段聲明

Null安全

上面我們看到kotlin是必須設置默認值的,就是爲了解決開發人員99%的崩潰異常(因爲基本都是NullPointerException崩潰[笑])
那我們就是要設置null初始對象呢其實也是可以的。

	var x = null
	var y:String? = null
    lateinit var z: String	//代表延遲初始化 需要在初始化中設置值

上面方式都可以設置爲null,但是要記得處理NullPointerException

那麼問題來了比如我們獲取到一段服務器的數據,肯定字段有可能爲空,我們應該如何處理呢!

class User {
    var name:String? = null
    var phone:String? = null
}

模擬使用如下

	//模擬只獲取到了name字段沒有phone字段
	var user = gson.fromJson("{name:\"李四\"}", User::class.java)

	println("userName = ${user?.name}")
	println("userPhone = ${user!!.phone}")

在使用的時候需要字段的時候加上?或者!!用來判斷是否爲空。
這兩個區別在於

"?"加在變量名後,系統在任何情況不會報它的空指針異常。
"!!"加在變量名後,如果對象爲null,那麼系統一定會報異常!

條件語句

if

我們在java中很常見的使用if也很簡單,kotlin其實也一樣只不過在這基礎上加了一些功能而已

	//java
	int c = 4
    String reslut = ""

    if(c == 2){
        reslut = "正確"
    }else if(c > 2){
        reslut = "太大了"
    }else{
        reslut = "太小了"
    }
    
    //kotlin
    var = 3
    var reslut = if(c == 2){
        "正確"
    }else if(c > 2){
        "太大了"
    }else{
        "太小了"
    }

可以看到if是可以直接返回值的,幫助減少多餘的代碼

when

when可以理解爲java的switch,還是加強版
還是上面的案例

    var reslut = when {
        c == 2 ->  "正確"
        c > 2 -> "太大了"
        else -> "太小了"
    }

看着好像就是if的變化但是when其實是可以判斷類型或者直接在一個when中做多樣事情

    var x = 11
    var y = "kotlin"
    var view:TextView? = null

    when(view){
        is TextView -> println("view is TextView")
        is ImageView ,is ImageButton -> println("view is Image")
        else -> println("I Do not know")
    }

    when {
        x in 1..10 -> log("x in 1-10")
        y.contains("k") -> println("$y contains k")
        else -> println("I Do not know")
    }

結果爲

I Do not know
kotlin contains k

我們可以看到不管是默認的switch判斷還是沒有對象的多種判斷(其實沒有對象判斷就是if-else的形式)when是一個很強大的條件語句

for

在原來java中我們for一般都是遍歷數組,kotlin中是可以快速遍歷數組和map等
我們這邊用1-10的遍歷寫下kotlin的一些常用功能

    for(i in 1..10){
        println(i)  //1 2 3 ... 10
    }
    
    for(i in 1 until 10){
        println(i)  //1 2 3 ... 9
    }
    
    for(i in 1..10 step 2){
        println(i)  //1 3 5 ... 9
    }
    
    for(i in 10 downTo 1){
        println(i)  // 10 9 8 ... 1
    }
    
    for(i in 10 downTo 1 step 2){
        println(i)  // 10 8 6 ... 2
    }

上面我們能看到一些變化

java kotlin
1 <= 10 1 .. 10
1 < 10 1 until 10
i+=2 step 2
倒序遍歷(java需要自己手動修改) downTo

還有就是直接遍歷list和map的簡單示例

        val array = arrayOf("a", "b", "c", "d")
        for (value in array){
            println(value)  //a b c d
        }
        
        for (i in array.indices){
            println(i)  //0 1 2 3
        }
        
        for((i, value) in array.withIndex()){
            println("$i=$value")    //0=a 1=b ...
        }
        
        val map = mapOf("a" to 77, "b" to "kotlin", "c" to View(this))
        for ((key, value) in map){
            println("$key=$value")  //a=77 b=kotlin c=android.view.View
        }

函數

java中的方法全部在kotlin中改爲了fun
區別如下

	//java
	void main(){}

	//kotlin
	fun main(): Unit{}	//Unit可以省略
	fun main(){}

	//java
    int add(int a, int b){
        return a + b;
    }

	//kotlin
    fun add(a: Int, b: Int): Int{
        return a + b
    }

還有這邊要提一下kotlin中不給fun設置可見修飾符privatepublic等默認情況是public 遇到個別關鍵字的時候就不是public

基本創建

java中創建類寫法和kotlin區別也是有的,具體情況如下

//java
public class JavaC {
    private String name = "JavaC";

    public JavaC() {}

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

//kotlin
class KotlinC {
    var name: String = "KotlinC"

    constructor()

    constructor(name: String) {
        this.name = name
    }

}

java中我們的構造函數是直接寫類名而在kotlin中使用關鍵字constructor代替

屬性的 getter/setter 函數

下面我們來說下屬性的get set
在java中我們可以使用setXXX getXXX來實現屬性的中轉,由於java中沒有空保護,所以我們一般都會在類的屬性get方法中加入類似如下方法

	private String name;
	
    public String getName() {
        return name == null ? "" : name;
    }

用於過濾掉Null錯誤,也可以在這邊實現強制修改值的功能等。在kotlin中我們需要在var的值下面直接調用get set方法和java區別挺大的,我們還是用上面的類做擴展 具體如下

public class JavaC {
    private String name = "JavaC";

    public JavaC() {

    }

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

    public String getName() {
        return name + ".class";
    }

    public void setName(String name) {
        this.name = "set " + name;
    }

    int add(int a, int b){
        return a + b;
    }
}

class KotlinC {
    var name: String = "KotlinC"
		//由於kotlin使用的是field代表變量所以必須直接寫在變量下方
        get(){
            return field + ".kt"
        }
        set(value) {
            field = "set " + value
        }

    constructor()

    constructor(name: String) {
        this.name = name
    }
}

	//具體使用
    JavaC javaC = new JavaC();
    javaC.setName("JC");
    println(javaC.getName());    //set JC.class

    val kotlinC = KotlinC()
    kotlinC.name = "KC"
    println(kotlinC.name)  //set KC.kt

類的繼承(: open override)

我們就用最常見的MainActivity用來說明
自動生成的代碼如下

//java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
//kotlin
class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

我們看到extends:替代、註解@Override被關鍵字override替代
這邊要說明下:不僅可以代表extends還可以代表implement
示例如下

interface Impl {}

//java
public class MainActivity extends AppCompatActivity implements Impl {}
//kotlin
class MainActivity : AppCompatActivity(), Impl {}

下面我們寫一個最經常使用BaseActivity類

abstract class BaseActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutId())

        initView()
        initData()
    }

    abstract fun getLayoutId(): Int

    abstract fun initView()

    abstract fun initData()
}

然後我們創建一個類繼承他

class NewActivity: BaseActivity() {
    override fun getLayoutId(): Int {
        return -1
    }

    override fun initView() {
    }

    override fun initData() {
    }
}

我們發現和java中基本一致,只需要實現抽象的方法就可以了。
這邊我們說下override在kotlin中是省略了protected關鍵字,override基本上是替代了protected我們需要關閉override的父類遺傳的話只需要在override前面加上final關鍵字關閉遺傳,比如之後我們在創建一個類繼承NewActivity時候發現錯誤

class NewActivity2: NewActivity() {
	//報錯:This type is final, so it cannot be inherited from
}

發現類默認是final修飾的,編譯器建議我們添加open字段,代碼如下

open class NewActivity: BaseActivity() {}

之後我們新類就不會報錯了!open打開了默認的final鎖,而final也可以鎖住override的遺傳性

類型的判斷和強轉(is as)

在java中我們用instanceof判斷參數是否是屬於該類在kotlin中是使用is,示例如下
首先我們先在NewActivity類中加入一個新的方法test NewActivity2中也繼承並重寫方法

open class NewActivity: BaseActivity() {
	...//其他代碼
    open fun test(){
        println("NewActivity test")
    }
}

class NewActivity2: NewActivity() {

    override fun test(){
        println("NewActivity2 test")
    }
}

然後我們調用方法

    val new1:Activity = NewActivity()
    val new2:Activity = NewActivity2()

    if (new1 is NewActivity) {
        new1.test()		//NewActivity test
    }

    if (new2 is NewActivity) {
        new2.test()		//NewActivity2 test
    }

我們發現kotlin幫我們省略了一些代碼 在java中需要((NewActivity) new1).test()這樣實現
那麼我們直接強轉代碼如下

	//java
	((NewActivity) new1).test();
	
	//kotlin
	(new1 as NewActivity).test()

如果我們強轉失敗呢,as明顯是可能轉換失敗的,這邊還是使用kotlin的?用來直接進行Null保護

    val new3: Activity = MainActivity()
    (new3 as? NewActivity)?.test()

這段代碼直接就會不執行

總結

算是kotlin基礎開頭的學習吧!繼續學習了!

資料

谷歌官方kotlin地址
Kotlin 的變量、函數和類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章