Kotlin-Object关键字作用

Object关键字使用场景:匿名内部类、单例、伴生对象。
匿名内部类

Kotlin匿名内部类定义使用跟Java类似,如何定义这里就不多赘述了。

不过它有一个增强的点,Java的匿名内部类不能再继承接口,而Kotlin可以。

以下匿名内部类在实现I1接口的基础上,再实现I2、 I3两个接口,相当于增强能力。被监听者根据不同场景进行回调,例如某场景只需要回调I1,某场景需要回调I2、I3。

Java要实现此功能,需要定义一个内部类,Kotlin会比较灵活一些。

    fun test() {
        val listener = object : I1, I2, I3 {
            override fun onSuccess1() {}
            override fun onSuccess2() {}
            override fun onSuccess3() {}
        }
        setListener(listener)
    }
    private fun setListener(listener: I1) {
        //dosomething
        listener.onSuccess1()
        if (listener is I2) {
            listener.onSuccess2()
        }
        if (listener is I3) {
            listener.onSuccess3()
        }
}
单例

Kotlin实现单例是非常简单的,只要用object描述类名即可。

object A {
     fun test(){}
}
    
//反编译代码
public final class A {
   @NotNull
   public static final A INSTANCE;
   public final void test() {}
   private A() {}

   static {
      A var0 = new A();
      INSTANCE = var0;
   }
}

看了下反编译的代码,原来是在类A初始化的时候就创建实例了。

不过这种方式有两个问题

  1. 可能会浪费性能,因为在没有使用就已经创建了;
  2. 无法传入参数,对于Android平台是很不友好的。
伴生对象

伴生对象是类中的静态对象,只能内部实例化且只有一个,可以用来定义类的静态变量、函数。

class A {
    companion object {
        const val name: String = "A"//1
        fun getInstance(): A {//2
            return A()
        }
    }
}
  • 注释1,定义了静态变量name;
  • 注释2,定义了静态方法getInstance获取实例对象;

反编译看看

public final class A {
   @NotNull
   public static final String name = "A";//1
   @NotNull
   public static final A.Companion Companion = new A.Companion();//2

   public static final class Companion {//3
      @NotNull
      public final  A getInstance() {//5
         return new A();
      }
      private Companion() {//4
      }

      public Companion(DefaultConstructorMarker $constructor_marker) {//6
         this();
      }
   }
}
  • 注释1,对应companion object{}中定义的静态变量name;
  • 注释2、3、4,定义了静态内部类Companion,且构造函数是私有,A实例化了静态变量Companion;
  • 注释5,对应companion object{}中定义的静态函数getInstance;
  • 注释6,虽然也定义了public构造函数,但观察入参类型得知,该构造函数只能是编译器调用,而我们开发者是无法调用的。
    所以我们知道,Kotlin的companion object{},是对应一个对象,也叫伴生对象,
    该对象类会描述我们定义的静态函数(静态变量好像不属于该类)。
一个有意思的细节
class A {
    companion object {
        const val name: String = "A"
        @JvmStatic//1
        fun getInstance(): A {
            return A()
        }
    }
}

 //加注解前,Java调用
  B.Companion.getInstance();
 //加注解后,Java调用
 B.getInstance();
  • 注释1:增加@JvmStatic注解是为了方便Java调用,那么反编译以后A中会增加定义getInstance函数,不过其内部还是调用伴生对象的getInstance。
    大家可以反编译看看。

以上分析有不对的地方,请指出,互相学习,谢谢哦!

你可能感兴趣的:(Kotlin-Object关键字作用)