安卓語言基礎之Kotlin的面向物件程式設計

語言: CN / TW / HK

theme: smartblue

本文正在參加「金石計劃 . 瓜分6萬現金大獎」

前言

強大而靈活的RecyclerView Adapter——BRVAH(框架引入與BaseQuickAdapter使用篇) - 掘金 (juejin.cn)這篇文章中,我自定義了一個屬性類,但其實當時我寫的時候是恍惚了好一陣,因為習慣用Java語言開發安卓的我,一時不知道用Kotlin如何寫類與其構造方法,異常尷尬,於是立刻翻出教程學習起來,然後才繼續完成了這個Adapter的Demo,下面我們就來看看如何使用Kotlin完成面向物件程式設計吧!

image.png

正篇

類的寫法

和Java一樣的地方是都要用class關鍵字: ```Kotlin class Person { var name = "" var age = 0

fun profile() {
    println("name : $name, age : $age")
}

} 也是大括號裡面寫成員變數和成員方法,例項化也很簡單:Kotlin val p = Person() ``` 只是沒有new這個關鍵字,這是Kotlin的機制。

繼承

Kotlin的繼承不需要寫extends關鍵字,而且Kotlin的繼承機制也與Java不一樣,在Kotlin中任何一個非抽象類預設都是不可繼承的,原因與val關鍵字類似,因為類和變數一樣,最好不可變,如果一個類允許被繼承,它就無法預知子類會如何實現,從而導致出現一些未知風險,所以當一個類不是用來繼承的,在Java中也應該用final宣告,禁止其繼承。

而Kotlin已經主動幫我們做好了,它預設所有非抽象類都不可被繼承,而抽象類是不能直接例項化,需要子類繼承才能建立例項,所有抽象類就是必須要被繼承才行。

但如果我們想要讓一個類可以被繼承,其實只需要加上關鍵字open即可: ```Kotlin open class Person { var name = "" var age = 0

fun profile() {
    println("name : $name, age : $age")
}

} 然後在Kotlin中Java的繼承關鍵字extends變成了“:”(冒號):Kotlin class Teacher : Person() { var num = 0 var className = "" } ``` 我們看到父類還加上了括號,這就是和下面要說的建構函式有關

建構函式

```Kotlin open class Person( val name : String, val age : Int ) { fun profile() { println("name : $name, age : $age") } }

class Teacher(var num : Int, var className : String, name: String, age: Int ) : Person(name, age) {

} ``` 我們可以看到和Java的建構函式不同,它不是寫在類方法體的,而是像方法宣告引數一樣寫在類名後的小括號內,所以父類繼承時也就需要小括號,同時我們將子類Teacher後的這個小括號內容稱作主建構函式,任何一個類只能有一個主建構函式,當然,有主建構函式,也會有次建構函式,這裡先不過多闡述,後面有時間再更新到本文中。

有建構函式的類例項化: Kotlin val teacher = Teacher(25, "A", "SchoolPerson", 30)

介面

Kotlin的介面和Java的介面宣告類似: Kotlin interface Teach { fun teach() fun work() } 繼承後需要去實現介面的所有方法,繼承不需要用Java的implements關鍵字,還是使用冒號,多個類時中間用逗號分開,介面不用名稱後加小括號,因為它沒有建構函式可調: ```Kotlin class Teacher(var num : Int, var className : String, name: String, age: Int ) : Person(name, age), Teach { override fun teach() { TODO("Not yet implemented") }

override fun work() {
    TODO("Not yet implemented")
}

} ``` 其中,override為Kotlin重寫方法的關鍵字,和Java的@Override註解類似

此外,Kotlin也支援介面函式預設實現,即可以在介面中對函式實現,然後在實現介面時就不用強制實現該函式,自由選擇是否實現該函式,不實習就呼叫預設實現方法: Kotlin interface Teach { fun teach() //預設實現 fun work() { println("Work!!") } } 繼承後可以選擇對已經預設的work方法實現或不實現:

image.png

預設實現去除繼承中的實現方法不報錯:

image.png

未實現繼承後也不實現的話會報錯:

image.png

這種使用介面的程式設計方式也叫面向介面程式設計,亦稱多型。

資料類

資料類通常用於將伺服器端或資料庫的資料對映到記憶體中,為程式設計邏輯提供資料模型的支援,我們常說的MVC,MVP,MVVM這些架構模式的M即指代資料類

前言中那個圖片其實就是想寫資料類但當時還不知道Kotlin如何寫就導致出現了個四不像的,但也勉強符合預期,後面會進行更正,那麼資料類該如何寫呢,我之所以寫錯就是因為Java中資料類實在不一樣,在Java中我們通常要重寫equals()、hashCode()和toString()方法,讓這個類擁有資料類的功能: ```Java public class ModelDemo { String name; int age;

public ModelDemo(String name, int age) {
    this.name = name;
    this.age = age;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof ModelDemo)) return false;
    ModelDemo modelDemo = (ModelDemo) o;
    return age == modelDemo.age && Objects.equals(name, modelDemo.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

@Override
public String toString() {
    return "ModelDemo{" +
            "name='" + name + ''' +
            ", age=" + age +
            '}';
}

} 而在Kotlin中,只要你加上關鍵字data就能自動幫你處理好這些,不需要做這些無用的工作:Kotlin data class ModelDemo(val name: String, val age: Int) 就這一句,簡簡單單。然後一樣可以實現上面Java程式碼重寫的方法的作用:Kotlin val modelDemo = ModelDemo("Name", 18) val modelDemo1 = ModelDemo("Name", 18) println(modelDemo) println(modelDemo == modelDemo1) ```

image.png

單例類

首先我們瞭解一下單例模式:

單例模式,最常用、最基礎的設計模式之一,可用於避免建立重複物件,在全域性最多隻能擁有一個例項。

單例模式的寫法很多,我們這邊先看一下Java的一種常見寫法: ```Java public class SingleDemo {

private static SingleDemo instance;

public SingleDemo() {}

public synchronized static SingleDemo getInstance() {
    if (instance == null) {
        instance = new SingleDemo();
    }
    return instance;
}

public void singleDemoTest() { System.out.println("singleDemoTest is called"); } } 呼叫:Java SingleDemo singleDemo = SingleDemo.getInstance(); singleDemo.singleDemoTest(); Java中看起來實現單例也不難,但當我看到Kotlin中時,真的笑了:Kotlin object SingleDemo { } 對,這就是Koltin版的單例,如果再加上Java中實現的方法:Kotlin object SingleDemo { fun singleDemoTest() { println("singleDemoTest is called") } } 呼叫看起來像在使用Java靜態方法的呼叫,其實是Kotlin已經幫我們自動建立好了SingleDemo的例項,且會保證全域性只存在一個SingleDemo例項:Koltin SingleDemo.singleDemoTest() ``` 只能說不愧是晚出來的語言,優勢真明顯,只需要把class關鍵字換成object,一個單例簡簡單單完成建立。

總結

本文將Kotlin的面向物件程式設計介紹了一遍,真的感受到了Kotlin的方便與優勢,感謝大家的閱讀!