Kotlin基礎 — object

Elson_6發表於2018-03-05

目錄

  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()
複製程式碼

相關文章