iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
Mobile Development

大一之 Android Kotlin 自習心路歷程系列 第 4

[Day 4] Android in Kotlin: Object 與 Singleton

  • 分享至 

  • xImage
  •  

Kotlin 中沒有 java 的 static 修飾詞,如果想要使用靜態的概念,可以用 object 來實現。

什麼是 Singleton?

Singleton 中文稱為「單例模式」,是一種程式的設計模型。它提出單例的 class 只會有一個實體的概念,確保了資料的正確等等。
如果想要在 kotlin 中使用單例模式,object 幫我們解決了一切。因為 object 只有 init{},沒有 constructor,也就是說,它不能在其他地方被 「new」 出來

而 object 又被分為兩種,Expressions 跟 Declarations

Object Expressions

這種 object 沒有名字,並繼承於其他類別或實作其他介面。

範例:在做按鈕的點擊監聽器時,需要一個物件,就可以用 object 來當作,感覺很像是 java 裡的 new 一個監聽器,這就是一種Expressions 的寫法,我不需要給他一個名字就能做使用。

btn.setOnClickListener(object : View.OnClickListener{
    override fun onClick(p0: View?) {
        TODO("Not yet implemented")
    }
})

Object Declarations

這種 object 會帶名字。並且裡面的成員都會是靜態的
比如說

object Robot{
    var color: String= "white"
}
Robot.color= "Blue"
Robot.color= "Yellow"

所以最後 Robot.color 回傳的是 "Yellow"

Companion Object

Companion 中文稱為「伴生」,在 kotlin 中,並沒有類似於 java 的 static 的修飾詞,所以如果你只想要一個 class 有靜態的成員或方法,而不是整個變成靜態的,那就要採用 companion object 的寫法。基本上,可以將 companion object 區塊視為靜態。

fun main() {
    Robot.Color.color= "Blue"
    Robot.Color.color= "Yellow"
}
class  Robot{
    companion object Color{
        var color= "White"
    }
}

寫在 class 裡面框起來。使用時要加個 object 的名字。

println("${Robot.Color.color}")

回傳答案為 Yellow

companion object 也可以不用名字,則用 Companion 表示

println("${Robot.Companion.color}")

回傳答案當然也是 Yellow

在這個範例裡面,是直接用 class 名來呼叫成員的,所以可以省略不寫,就算有同名的一般成員存在,也不影響答案。

class  Robot{
    var color= "Black"
    companion object{
        var color= "White"
    }
}

另外建一個實體看看 color 是什麼

fun main() {
    println("${Robot.color}")
    
    val myRobot = Robot()
    println("${myRobot.color}")
}

回傳答案:

White
Black

以上的範例都是用「靜態成員」當作示範,當然方法也可以靜態,方法大同小異就不再贅述啦

在我的作業中,也有一個區塊是使用 companion object
(只保留部分 code)

class Repository(private val accountingDao: AccountingDao) {
    companion object Date {
        private val dateFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
        var currentDate = MutableLiveData<LocalDate>(LocalDate.parse(LocalDate.now().toString(), dateFormatter))
        var selectedDate = MutableLiveData<LocalDate>(LocalDate.parse(LocalDate.now().toString(), dateFormatter))
    }
}

其實就只是靜態成員的觀念而已,我有眾多的 activity 跟 fragment 會使用到日期,而日期又有分兩個,「今天的日期」跟「選擇的日期」

像是在這個 viewModel 裡面 (只保留部分 code)

var selectedDate: MutableLiveData<LocalDate>

init{
    selectedDate= Repository.selectedDate
}

在其他地方從 companion object 拿就能拿到相同的日期做使用。


上一篇
[Day 3] Android in Kotlin: NonNull and Nullable
下一篇
[Day 5] Android in Kotlin: 高階函式 與 Lambda Function 分享
系列文
大一之 Android Kotlin 自習心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
JellyHugo
iT邦新手 2 級 ‧ 2020-11-15 20:12:17

版大您好!!
我是初學Kotlin的新手,想像您請教下companion object的問題。
從版大文章可以知道companion object類似於Java的static Methond與static variable是很相似的。但若在Class指宣告Object是不是也是一樣的效果呢?

例如:

class TestClass(){
	companion object Color{
        var color = "white"
    }
}

class TestClass2(){
	object Color{
        var color = "White"
    }
}

fun main(){
    println("${TestClass.Color.color}")
    TestClass.Color.color = "Yellow"
	println("${TestClass.Color.color}")
    
    
    println("${TestClass2.Color.color}")
    TestClass2.Color.color = "Yellow"
    println("${TestClass2.Color.color}")
}

white
Yellow
White
Yellow

是的,在你這個範例中,成果是一樣的。
companion object 跟 object 不同的地方在於:companion object 不能單獨存在,一定要跟著一個 class,且一個 class 中只能有一個;但 object 可以單獨存在,一個 class 也可以有多個不同的 object。

希望這樣有幫助到你 ^^

JellyHugo iT邦新手 2 級 ‧ 2020-11-16 21:14:03 檢舉

了解了~~ companion object像是代表static意義一樣,可以方便寫程式的溝通。(static變數|方法 都統一放在companion object裡面)
我解釋得有點亂...希望別誤導

感謝版大~~

我要留言

立即登入留言