kotlin语言学习08 ——kotlin接口类、抽象类、伴生对象

本小节主要介绍kotlin接口类、抽象类、伴生对象的相关知识。

1、kotlin的接口

在Java中,从jdk8开始,Java的接口中可以有默认方法的实现。kotlin的接口与Java相似。

1.1、kotlin定义接口,关键字Interface

interface A {
    fun method()
}

kotlin 接口类中的方法可以实现,也可以不实现。

interface A {
    // 加上 花括号就可以实现,不加就不实现
    fun method() {
        println("A")
    }
}

1.2、kotlin接口类的实现

interface A {
    // 加上 花括号就可以实现,不加就不实现
    fun method() {
        println("A")
    }
}

下面是对接口的实现。

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

1.3、kotlin接口的实现和继承相同名称的方法

在kotlin中,当接口的名字和要继承类中有相同方法名时,kotlin使用 super.method() 来区分两个不同类中的方法。

// 接口类
interface A {
    // 加上 花括号就可以实现,不加就不实现
    fun method() {
        println("A")
    }
}

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

以上类中窜在相同的方法名,此时:

/**
 * C 继承了B,并实现了 A,里面都有method方法,比较混乱,所以必须要明确使用的那个方法
 *
 * 拥有签名的相同的方法,必须明确,使用 super.method()
 */
class C: A,B() {
    override fun method() {
        println("C")
        super.method()
        super.method()
    }
}

2、kotlin中的抽象类

kotlin中的抽象类和Java中的抽象类基本上类似。 使用 abstract 关键字进行修饰

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

    }
}

abstract class ChildCLass: BaseClass() {

}

3、kotlin的伴生对象

3.1、对象声明

在Java送使用 new 关键字,将对象创建出来并且放在内存中。但是在kotlin中可以直接声明一个对象,使用object关键字。

// 使用object关键字声明一个对象,叫 MyObject
object MyObject {
    fun method() {
        println("method")
    }
}

上面对象中的方法可以直接被调用。

fun main() {
    // 可以直接调用
    MyObject.method() // method
}

3.2、伴生对象

补充:

  • 在Java中,static关键字:一个类被static修饰后,那么这个类就可以通过类名直接被调用,这也是Java鼓励的一种调用方式。
  • 我们可以吧Java中的static的方法当做一种全局方法,但是在kotlin中 没有static的方法。
  • 在大多数情况下,kotlin推荐的做法是使用 包级别 的函数作为静态方法。
  • 所以,kotlin会将包级别的函数当做静态方法来看。

companion object : 伴生对象
伴生对象: 随着类的存在而存在,相当于实现了Java中的 static 方法,在kotlin中使用 companion关键字来修饰。

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

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

伴生对象和 static对象的关系:

  • kotlin中将 MyObject类以MyTest的内部类的方式而存在。
  • 注意: 虽然伴生对象的成员看似是Java中的静态成员,但是在运行期,他们依旧是真实对象的实例对象
  • 在Java上,kotlin可以使用让伴生对象成为真正的静态方法与属性,使用 @JvmStatic 注解来实现
  • 伴生对象在编译后会生成一个静态内部类 (可以通过反编译实现)

3.3、反编译伴生对象类

下面通过反编译的方式展示kotlin的伴生对象与Javastatic修饰类的关系。
使用javap命令反编译上面的kotlin编译后生成的字节码:

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();
}

关于kotlin反编译的知识,可以看我之前的教程,点这里。
通过上面反汇编出来的内容我们看到了类的结构,就是Java中的 static 修饰的类,进一步看该类的详细内容:

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."":()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."":(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
}

你可能感兴趣的:(kotlin语言学习08 ——kotlin接口类、抽象类、伴生对象)