1. 程式人生 > >快速學習Kotlin(四)類與物件

快速學習Kotlin(四)類與物件

Kotlin中的類

class Main{

}

class Main1 : AppCompatActivity(){

}

class Main2:AppCompatActivity(),View.OnClickListener{
    override fun onClick(v: View?) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

}

open class Main3{
    
}

open class Main4:AppCompatActivity(){
    
}

open class Main5:AppCompatActivity(),View.OnClickListener{
    override fun onClick(v: View?) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

}

上面程式碼中我們聲明瞭五種類的寫法。

在Kotlin中定義一個類,必須使用class關鍵字來修飾(例如Main);

如果這個類有父類則使用 " : " 來代表繼承(例如Main1);

如果有多重繼承或者有介面來例項化則可以直接在後面用逗號來隔開處理,而無需寫implements來實現介面(例如Main2),介面和父類可以沒有先後關係,先寫介面然後再寫父類也沒有任何的問題;

在kotlin中有一個關鍵字open,其代表這個類不為final。在kotlin中如果類沒有用open進行修飾,那麼kotlin會預設這個類是一個被public final修飾的類。

建構函式

在kotlin中,如果想在類中寫入建構函式,並且在建構函式中傳遞引數,那麼我們可以只寫在類的後面跟一個括號,在括號內填寫相應的引數。

class Person (name:String,age:Int){

    private var name:String;
    private var age:Int;
    
    init {
        this.name = name;
        this.age = age;
    }
}

我們看到,在Person這個類後面我們用括號括起來了兩個引數。於是這便是向Person類寫入了一個建構函式,,而當我們想要在建構函式中執行一些語句的話,我們便可以使用init這個關鍵字,這個關鍵字中的語句會在我們執行建構函式的時候同時執行。在這裡我們在init語句中將兩個引數進行賦值操作。

次級建構函式

當我們在寫一個類的時候可能有時候因為功能的不同,會寫很多個建構函式。在kotlin中次級建構函式需要使用constructor來修飾,並且次級建構函式必須直接或間接的繼承主建構函式。

class Student constructor(username: String, age: Int) {


    private val username: String = username
    private var age: Int = age
    private var address: String
    private var isMarried: Boolean


    init {
        this.address = "Beijing"
        this.isMarried = false
    }


    constructor(username: String, age: Int, address: String) :this(username, age) {

        this.address = address
    }


    constructor(username: String, age: Int, address: String, isMarried: Boolean) : this(username, age, address) {

        this.isMarried = isMarried
    }


}

可以看到在程式碼中,我們寫了兩個次級建構函式,並且每個函式後面都直接或間接的繼承了主建構函式。

訪問修飾符

在kotlin中總共有四種訪問修飾符

  • private: 代表這個類中的成員是這個類私有的別的類不能進行訪問。

  • public: 代表這個類或者其他所有的類都能夠訪問的到。

  • protected: 代表這個類或者這個類的繼承類都可以訪問這個成員

  • internal: 此為kotlin中特有的修飾符,其表示在這個模組內都能訪問到這個物件,但是對於跨模組卻不能訪問到。那麼什麼叫做模組呢?在Android常用編輯器Android Studio中我們有時候會通過檔案File去新建一個叫做module的,而這個module就是一個模組。而被internal修飾的物件,只能在這個module中訪問,不能在其他module中訪問。

伴生物件

在Java中我們常常會去使用一些工具類,對於工具類的編寫,一般都是直接在一個類中用static去修飾這個方法,然後通過類名.方法名直接呼叫。

public class Utils {

    public static boolean isEmpty(String str){
        return str.equals("");
    }
}

但是在kotlin中是沒有static這個關鍵字的,那麼在kotlin中該如何處理這種工具類的編寫呢?方法有兩種,

一種是之前講的,可以使用 @JvmStatic 來修飾工具類的方法然後直接呼叫。

object Utils{

    @JvmStatic
    fun isEmpty(str:String):Boolean {

        return str.equals("");
    }
}

fun test1(){
    Utils.isEmpty("test");
}

另外一種是使用伴生物件來進行修飾。

class Utils1{

    companion object {
        fun isEmpty(str:String):Boolean{
            return str.equals("");
        }
    }
}

fun test1(){
    
    Utils1.isEmpty("test");
}

伴生物件必須要在類中進行使用。用companion object兩個關鍵字進行宣告,後面用一個大括號括起來需要使用的函式,使用的時候直接通過類名.函式名稱即可。

那麼在Java中該如何呼叫這個kotlin中的伴生物件呢?其實也非常簡單,可以使用類名 + Companion + 函式名即可。

//java程式碼

public class Utils {

    public void test(){
        Utils1.Companion.isEmpty("test");
    }
}

實際上,在kotlin中程式會通過Companion這個關鍵字在編譯的時候生成一個靜態的物件,然後java通過這個靜態物件去呼叫Companion物件內部的一些函式。

編寫單例

在kotlin中編寫單例的方式有兩種,一種是通過object + @JvmStatic的方式來編寫單例。而另外一種單例的編寫我們可以使用伴生物件來實現。


fun test1(){

    var get = SingletonDemo.get()
}

class SingletonDemo private constructor() {
    companion object {
        private var instance: SingletonDemo? = null
            get() {
                if (field == null) {
                    field = SingletonDemo()
                }
                return field
            }
        @Synchronized
        fun get(): SingletonDemo{
            return instance!!
        }
    }

}

看到,我們通過伴生物件來編寫了一個懶漢式的單例模式。然後直接通過伴生物件的函式來獲取到SingletonDemo這個物件。

資料類——data

data可以說是在kotlin中常用的關鍵字。這個關鍵字一般是用來修飾一個類的,被修飾的這個類自動會生成get()/set()方法、toString()方法、hashCode()方法、equals()方法以及copy()方法,而不需要我們再特意去書寫這些常用的方法,大大節約了我們的書寫成本。

data class Person1(var name:String){

}

這裡需要注意,被data修飾的類必須至少需要一個構造方法,且裡面需要有至少一個引數。如果沒有構造方法的類不能被data修飾或者被修飾了會報錯。 這個其實也很好理解,因為被data修飾之後會有se()/get()方法,所以如果沒有構造方法來傳遞引數,那麼set()/get()方法根本沒有用。另外,資料類是一個public final型別,被data修飾的類不能再被open去修飾也不能等被繼承,不然程式會報錯。

如果覺得我的文章能夠幫助到你,也歡迎關注我的微信公眾號「晨雨細曲」,有新技術和知識會推送在這上面。