2016-07-14 96 views
82

「伴侶對象」的含義是什麼?到目前爲止,我一直在使用它來替換Java的static當我需要它。爲什麼我們使用「伴侶對象」作爲Kotlin中Java靜態字段的一種替代品?

我與困惑:

  • 爲什麼叫 「伴侶」?
  • 是否意味着要創建多個靜態屬性,我必須將它組合在companion object塊內?
  • 即時創建範圍限定於一類單一實例,我經常寫

companion object { 
    val singleton by lazy { ... } 
} 

這似乎是這樣做的unidiomatic方式。更好的方法是什麼?

回答

64
  • 什麼是 「同伴對象」 的本意?爲什麼叫做「同伴」?

    首先,科特林不使用的static成員的Java概念,因爲科特林具有用於描述與單身狀態連接的屬性和功能自身的concept of objects,和Java類的static一部分可以在單的術語來表達優雅:這是一個單獨的對象,可以通過類的名字來調用。因此命名:它是一個類的對象。

    它的名字曾經是class object and default object,但是後來的it got renamed to companion object這個更清晰,也與Scala companion objects一致。

    除命名外,它比Java static成員更強大:它可以擴展類和接口,並且可以引用它並將它傳遞給其他對象。

  • 這是否意味着創建多個靜態屬性,我必須組一起裏面companion object塊?

    是的,這是慣用的方式。或者您可以通過自己的意思,甚至組他們在非同伴對象:

    class MyClass { 
        object IO { 
         fun makeSomethingWithIO() { /* ... */ } 
        } 
    
        object Factory { 
         fun createSomething() { /* ... */ } 
        } 
    } 
    
  • 即時創建範圍限定於一類單一實例,我經常寫/*...*/這似乎像是在做的unidiomatic方式它。更好的方法是什麼?

    這取決於你在每個特定情況下需要什麼。你的代碼適合存儲綁定到一個類的初始化時的狀態,這個類在第一次調用它時被初始化。

    如果不需要它可以用一個類來連接,只需使用對象聲明:

    object Foo { 
        val something by lazy { ... } 
    } 
    

    您還可以刪除lazy { ... } delegation使財產初始化頭等艙的使用,就像Java靜態初始化器

    您可能還會找到有用的方法initializing singleton state

+0

好的和習慣的例子。 – Trein

13

爲什麼叫做「同伴」?

此對象是實例的伴侶。 IIRC有長時間的討論在這裏:upcoming-change-class-objects-rethought

這是否意味着創建多個靜態屬性,我必須組一起的同伴對象塊內?

是的。每個「靜態」屬性/方法都需要放在這個伴侶內。

即時創建範圍限定於一類單一實例,我經常寫

你不立即創建的單一實例。它是在首次訪問singleton時創建的。

這似乎是一個單一的方式做到這一點。更好的方法是什麼?

寧可與object Singleton { }一起定義一個單例類。請參閱:Object Declarations 您不必創建Singleton一個實例,只是用它像Singleton.doWork()

只要記住,科特林提供其他的東西來組織你的代碼。現在可以選擇簡單的靜態功能,例如你可以使用頂層函數。

0

爲什麼叫做「同伴」?

一個類中的對象的聲明可以被標記與同伴關鍵字:

val instance = MyClass.create() 

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

同伴對象的成員可以通過使用簡單的類名作爲限定符被稱爲

如果您只使用沒有「伴侶」的「對象」,您必須這樣做:

val instance = MyClass.Factory.create() 

在我的理解中,「夥伴」意味着這個對象是伴隨外部課堂的。

相關問題