kotlin語言學(xué)習(xí)08 ——kotlin接口類、抽象類、伴生對象

本小節(jié)主要介紹kotlin接口類、抽象類、伴生對象的相關(guān)知識。

1、kotlin的接口

在Java中,從jdk8開始,Java的接口中可以有默認方法的實現(xiàn)。kotlin的接口與Java相似。

1.1、kotlin定義接口,關(guān)鍵字Interface

interface A {
    fun method()
}

kotlin 接口類中的方法可以實現(xiàn),也可以不實現(xiàn)。

interface A {
    // 加上 花括號就可以實現(xiàn),不加就不實現(xiàn)
    fun method() {
        println("A")
    }
}

1.2、kotlin接口類的實現(xiàn)

interface A {
    // 加上 花括號就可以實現(xiàn),不加就不實現(xiàn)
    fun method() {
        println("A")
    }
}

下面是對接口的實現(xiàn)。

class C : A {
    // 方法重寫
    override fun method() {
        println("C")
    }
}

1.3、kotlin接口的實現(xiàn)和繼承相同名稱的方法

在kotlin中,當(dāng)接口的名字和要繼承類中有相同方法名時,kotlin使用 super<Class>.method() 來區(qū)分兩個不同類中的方法。

// 接口類
interface A {
    // 加上 花括號就可以實現(xiàn),不加就不實現(xiàn)
    fun method() {
        println("A")
    }
}

// 普通類
open class B {
    open fun method() {
        println("B")
    }
}

以上類中竄在相同的方法名,此時:

/**
 * C 繼承了B,并實現(xiàn)了 A,里面都有method方法,比較混亂,所以必須要明確使用的那個方法
 *
 * 擁有簽名的相同的方法,必須明確,使用 super<Class>.method()
 */
class C: A,B() {
    override fun method() {
        println("C")
        super<A>.method()
        super<B>.method()
    }
}

2、kotlin中的抽象類

kotlin中的抽象類和Java中的抽象類基本上類似。 使用 abstract 關(guān)鍵字進行修飾

/**
 * 抽象類
 */
open class BaseClass {
    open fun baseMethod() {

    }
}

abstract class ChildCLass: BaseClass() {

}

3、kotlin的伴生對象

3.1、對象聲明

在Java送使用 new 關(guān)鍵字,將對象創(chuàng)建出來并且放在內(nèi)存中。但是在kotlin中可以直接聲明一個對象,使用object關(guān)鍵字。

// 使用object關(guān)鍵字聲明一個對象,叫 MyObject
object MyObject {
    fun method() {
        println("method")
    }
}

上面對象中的方法可以直接被調(diào)用。

fun main() {
    // 可以直接調(diào)用
    MyObject.method() // method
}

3.2、伴生對象

補充:

  • 在Java中,static關(guān)鍵字:一個類被static修飾后,那么這個類就可以通過類名直接被調(diào)用,這也是Java鼓勵的一種調(diào)用方式。
  • 我們可以吧Java中的static的方法當(dāng)做一種全局方法,但是在kotlin中 沒有static的方法。
  • 在大多數(shù)情況下,kotlin推薦的做法是使用 包級別 的函數(shù)作為靜態(tài)方法。
  • 所以,kotlin會將包級別的函數(shù)當(dāng)做靜態(tài)方法來看。

companion object : 伴生對象
伴生對象: 隨著類的存在而存在,相當(dāng)于實現(xiàn)了Java中的 static 方法,在kotlin中使用 companion關(guān)鍵字來修飾。

class MyTest() {
    /**
     * 定義類(伴生對象)
     *  MyObject伴隨 MyTest 類而存在
     *
     *  @MyObject :類似于重命名,作用不大,可以省略
     *  kotlin中提供了默認的名字 Companion
     */
    companion object MyObject {
        val A: Int = 100;

        @JvmStatic
        fun method() {
            println("this is companion object")
        }
    }
}

伴生對象和 static對象的關(guān)系:

  • kotlin中將 MyObject類以MyTest的內(nèi)部類的方式而存在。
  • 注意: 雖然伴生對象的成員看似是Java中的靜態(tài)成員,但是在運行期,他們依舊是真實對象的實例對象
  • 在Java上,kotlin可以使用讓伴生對象成為真正的靜態(tài)方法與屬性,使用 @JvmStatic 注解來實現(xiàn)
  • 伴生對象在編譯后會生成一個靜態(tài)內(nèi)部類 (可以通過反編譯實現(xiàn))

3.3、反編譯伴生對象類

下面通過反編譯的方式展示kotlin的伴生對象與Javastatic修飾類的關(guān)系。
使用javap命令反編譯上面的kotlin編譯后生成的字節(jié)碼:

Compiled from "ObjectDeclaration.kt"
public final class com.liang.kotlin.classAndObject.MyTest {
  public static final com.liang.kotlin.classAndObject.MyTest$MyObject MyObject;
  public com.liang.kotlin.classAndObject.MyTest();
  static {};
  public static final int access$getA$cp();
  public static final void method();
}

關(guān)于kotlin反編譯的知識,可以看我之前的教程,點這里。
通過上面反匯編出來的內(nèi)容我們看到了類的結(jié)構(gòu),就是Java中的 static 修飾的類,進一步看該類的詳細內(nèi)容:

Compiled from "ObjectDeclaration.kt"
public final class com.liang.kotlin.classAndObject.MyTest {
  public static final com.liang.kotlin.classAndObject.MyTest$MyObject MyObject;

  public com.liang.kotlin.classAndObject.MyTest();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #39                 // class com/liang/kotlin/classAndObject/MyTest$MyObject
       3: dup
       4: aconst_null
       5: invokespecial #44                 // Method com/liang/kotlin/classAndObject/MyTest$MyObject."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #37                 // Field MyObject:Lcom/liang/kotlin/classAndObject/MyTest$MyObject;
      11: bipush        100
      13: putstatic     #20                 // Field A:I
      16: return

  public static final int access$getA$cp();
    Code:
       0: getstatic     #20                 // Field A:I
       3: ireturn

  public static final void method();
    Code:
       0: getstatic     #37                 // Field MyObject:Lcom/liang/kotlin/classAndObject/MyTest$MyObject;
       3: invokevirtual #41                 // Method com/liang/kotlin/classAndObject/MyTest$MyObject.method:()V
       6: return
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容