Kotlin基础 — object

536 阅读3分钟

目录

  1. object 表达式
    1.1 赋值给变量的 object 表达式
    1.2 作为方法参数的 object 表达式

  2. object 对象声明
    2.1. 直接声明 object 对象
    2.2 继承自接口(抽象类)的对象声明
    2.3 类内部的对象声明

  3. 伴生对象 Companion Object
    3.1 普通的伴生对象
    3.2 在伴生对象中实现接口
    3.3 伴生对象的扩展


1. Object 表达式

创建匿名内部类的形式:object: ClassName {...}

// Handler 匿名表达式
val handler: Handler = object: Handler() {
    override fun handleMessage(msg: Message?) {
        super.handleMessage(msg)
        when(msg?.what) {
            1 -> "Expression1"
            2 -> "Expression2"
        }
    }
}

/*
 * 方法中的匿名内部类的创建,当然这个点击事件在Anko中有更简单的写法;
 * TextView(ctx).setOnClickListener { 
 *     //...
 * }
 */
TextView(ctx).setOnClickListener(object: View.OnClickListener{
    override fun onClick(v: View?) {
        //...
    }
})

2. object 对象声明

2.1 直接声明 object 对象

在Java中,单例的声明可能具有多种方式:如懒汉式、饿汉式、静态内部类、枚举等;
在Kotlin中,单例模式的实现只需要一个 object 关键字即可;

// Kt文件中的声明方式: object 关键字声明,其内部不允许声明构造方法
object SingleObject {
    fun test() {
	    //...
    }
}

// 调用方式:类名.方法名()
class Main {
	fun test() {
		SingleObject.test() //在class文件中,会自动编译成SingleObject.INSTANCE.test();调用方式
	}
}

// ----------------源码和字节码分界线 ---------------

//Kotlin文件编译后的class代码如下:
public final class SingleObject {
   public static final SingleObject INSTANCE;

   public final void test() {
   }

   private SingleObject() {
      INSTANCE = (SingleObject)this;
   }

   static {
      new SingleObject();
   }
}

2.2 继承自接口(抽象类)的对象声明

// Kt原文件代码
object MyMachine: Machine() {
    override fun start() {
        //...
    }
}
abstract class Machine {
    abstract fun start()
    open fun stop() {}//只有被open修饰过的方法才能被继承,否则默认是final类型的,不可被重写;
}

// ----------------源码和字节码分界线 ---------------

// 以下是编译后裔的class文件
public final class MyMachine extends Machine {
   public static final Single INSTANCE;

   public void start() {
      String var1 = "not implemented";
      throw (Throwable)(new NotImplementedError("An operation is not implemented: " + var1));
   }

   private MyMachine() {
      INSTANCE = (MyMachine)this;
   }

   static {
      new MyMachine();
   }
}

public abstract class Machine {
   public abstract void start();
   public void stop() {}
}

2.3 类内部的对象声明

class Single {
    object Manage {//类内部的对象声明,没有被inner修饰的内部类都是静态的
        fun execute() {
			//...
        }
    }
}

// ----------------源码和字节码分界线 ---------------

public final class Single {
   // 静态内部类
   public static final class Manage {
      public static final Single.Manage INSTANCE;

      public final void execute() {}

      private Manage() {
         INSTANCE = (Single.Manage)this;
      }

      static {
         new Single.Manage();
      }
   }
}

3. 伴生对象 Companion Object

伴生对象是一个声明在类中的普通对象,它可以有名称 (默认为Companion) ,它可以实现一个接口或者有扩展函数或属性。

3.1 普通的伴生对象

class MyClass {
    companion object Factory {
		val url = ""
        fun create(): MyClass = MyClass()
    }
}

// 调用的时候,直接使用 类名.属性名 或 类名.方法名
MyClass.url
MyClass.create()

3.2 在伴生对象中实现接口

interface Factory<T> {
    fun create(): T
}

class MyClass {
	// 伴生类中实现接口
    companion object : Factory<MyClass> {
	    val url = ""
	    // 实现接口的抽象方法
        override fun create(): MyClass = MyClass()
    }
}

// 调用
class Main {
	fun test() {
		setFactory(MyClass) // 这里传递进去的MyClass对象,其实就是MyClass的伴生对象
	}

    fun <T> setFactory(factory: Factory<T>) {
        factory.create()
    }
}

3.3 伴生对象的扩展

伴生对象的扩展和普通类的扩展一致

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

// 伴生类的扩展
fun MyClass.Factory.fun_name() = ...功能代码...

// 调用
MyClass.Factory.fun_name()