Kotlin使用心得(十):object與單例模式
寫在前面
本文將穿插大部分從以下這篇文章翻譯過來的內文:
我們將先從如何使用object
實作單例模式(Singleton Pattern)開始探討,後續再介紹object
的其它用法。
正文開始
Java有Java實現單例模式的方式,Kotlin也有,讓我們先從Java開始看吧!
在Java中實現單例模式
起手式:
- 給一個名為「instance」的field
- 調用
getInstance()
方法的時候,instance
若為空,則實例化一個 - 進行實例化的建構式訪問權限必須為
private
做好啦:
但是這樣可能會有資料不同步的問題,加入synchronized
關鍵字來保證安全性:
耶!我們大功告成~~~開趴囉~
在兼顧易讀性的狀況下,我們僅僅使用了18行代碼。
在Kotlin中實現單例模式
藉由使用object
關鍵字,一行解決全世界:
Java開發者:……(覺得無言)
這種做法也稱為所謂的「Object Declaration」。
Kotlin實現單例模式背後的機制
可以試著decompile看看:
可以發現解開來的Java代碼,就是建立了一個唯一的實例。
object的其它用法
說好的建構式呢
剛剛我們已經用了Object Declaration實例化了一個物件。那object
和class
一樣嗎?它一樣有建構式嗎?我們來編譯看看:
object Singleton()
object Singleton(arg1:Int)
Compiler:
Constructors are not allowed for objects
翻譯:你來錯棚了……用object不能使用建構式!
相等於Java的static用法
要使用相等於Java的static用法的話,你得在object
關鍵字前加上companion
關鍵字。以下面的代碼為例,加上companion
後不管有沒有額外call Companion
,都可以直接呼叫得到isDebug
屬性:
當作匿名類別使用
先看範例,我們創造了一個Vehicle
類別,Car
與Truck
都是一種Vehicle
,所以可以加入類型為Vehicle
的列表vehicles
:
如果我們要快速增加一個匿名類別的話,可以搭配object
使用所謂的「Object Expression」,我們來新增一個有10個輪子的Vehicle
:
vehicles.add(object : Vehicle("custom", 10) {})
這個新增的匿名類別,也是可以加入類型為Vehicle
的列表vehicles
的:
來看看需要覆寫方法的情況,也是OK:
當作匿名物件使用
當我們需要一個物件,而且這個物件使用場景不多,不需要另外創建一個class的時候,可以考慮使用object
:
以上這種方式也是Object Expression的一種唷!
好了,來考考大家,當今天我們有兩個用object
創造出來的匿名物件,物件中屬性的值都相同,甚至連方法都一樣,那這兩個物件是相等的嗎?
給你5秒鐘想想下面代碼println()
出來的結果:
第一題:
println(shapeA==shapeB)
第二題:
println(shapeA===shapeB)
5
4
3
2
1
答案揭曉!
Compiler:
cannot be applied to ‘<no name provided>’ and ‘<no name provided>’
翻譯:哈哈,你被耍了,連編譯都無法編譯,根本不用比
因為我們用object建立出來的是匿名物件,類別為<no name provided>。
和匿名類別不一樣,匿名類別至少還繼承/實作了類別/介面,所以下次別被騙辣。
object用法,需要注意的地方
Object Declaration與Object Expression有本質上的差異,請大家多多注意:
- Object Declaration是在第一次被訪問到時,延遲初始化用的
- Object Expression是立即初始化的