Warum verwenden wir "Begleitobjekt" als eine Art Ersatz für statische Java-Felder in Kotlin?

145

Was ist die beabsichtigte Bedeutung von "Begleitobjekt"? Bisher habe ich es nur verwendet, um Java zu ersetzen, staticwenn ich es brauche.

Ich bin verwirrt mit:

  • Warum heißt es "Begleiter"?
  • Bedeutet dies, dass ich mehrere statische Eigenschaften innerhalb eines companion objectBlocks zusammenfassen muss, um sie zu erstellen ?
  • Um sofort eine Singleton-Instanz zu erstellen, die sich auf eine Klasse bezieht, schreibe ich oft

::

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

Das scheint eine unidiomatische Art zu sein. Was ist der bessere Weg?

Randy Sugianto 'Yuku'
quelle

Antworten:

108
  • Was ist die beabsichtigte Bedeutung von "Begleitobjekt"? Warum heißt es "Begleiter"?

    Erstens verwendet Kotlin das Java-Konzept von staticMitgliedern nicht, da Kotlin ein eigenes Konzept von objects zur Beschreibung von Eigenschaften und Funktionen hat, die mit dem Singleton-Status verbunden sind, und der Java- staticTeil einer Klasse elegant als Singleton ausgedrückt werden kann: Es ist ein Singleton-Objekt, das kann durch den Klassennamen aufgerufen werden. Daher die Benennung: Es ist ein Objekt, das mit einer Klasse geliefert wird.

    Sein Name war früher class objectunddefault object , aber dann wurde er umbenannt,companion object was klarer ist und auch mit Scala-Begleitobjekten übereinstimmt .

    Abgesehen von der Benennung ist es leistungsfähiger als Java- staticMitglieder: Es kann Klassen und Schnittstellen erweitern und Sie können es wie andere Objekte referenzieren und weitergeben.

  • Bedeutet dies, dass ich mehrere statische Eigenschaften innerhalb eines companion objectBlocks zusammenfassen muss, um sie zu erstellen ?

    Ja, das ist der idiomatische Weg. Oder Sie können sie sogar nach ihrer Bedeutung in Nicht-Begleitobjekten gruppieren:

    class MyClass {
        object IO {
            fun makeSomethingWithIO() { /* ... */ }
        }
    
        object Factory {
            fun createSomething() { /* ... */ }
        }
    }
    
  • Um sofort eine Singleton-Instanz zu erstellen, die sich auf eine Klasse bezieht, schreibe ich oft, /*...*/was wie eine unidiomatische Methode erscheint. Was ist der bessere Weg?

    Es kommt darauf an, was Sie im Einzelfall brauchen. Ihr Code eignet sich gut zum Speichern des Status, der an eine Klasse gebunden ist, die beim ersten Aufruf initialisiert wird.

    Wenn Sie es nicht benötigen, um mit einer Klasse verbunden zu werden, verwenden Sie einfach die Objektdeklaration:

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

    Sie können die lazy { ... }Delegierung auch entfernen , um die Eigenschaft bei Verwendung der ersten Klasse zu initialisieren, genau wie bei statischen Java-Initialisierern

    Möglicherweise finden Sie auch nützliche Möglichkeiten zum Initialisieren des Singleton-Status .

Hotkey
quelle
Schöne und idiomatische Beispiele.
Trein
19

Warum heißt es "Begleiter"?

Dieses Objekt ist ein Begleiter der Instanzen. IIRC gab es hier eine lange Diskussion: bevorstehende-Änderung-Klasse-Objekte-Überdenken

Bedeutet dies, dass ich zum Erstellen mehrerer statischer Eigenschaften diese im Begleitobjektblock zusammenfassen muss?

Ja. Jede "statische" Eigenschaft / Methode muss in diesem Begleiter platziert werden.

Um sofort eine Singleton-Instanz zu erstellen, die sich auf eine Klasse bezieht, schreibe ich oft

Sie erstellen die Singleton-Instanz nicht sofort. Es wird beim ersten Zugriff erstellt singleton.

Das scheint eine unidiomatische Art zu sein. Was ist der bessere Weg?

Gehen Sie lieber mit object Singleton { }, um eine Singleton-Klasse zu definieren. Siehe: Objektdeklarationen Sie müssen keine Instanz von erstellen Singleton, verwenden Sie sie einfach soSingleton.doWork()

Denken Sie daran, dass Kotlin andere Dinge anbietet, um Ihren Code zu organisieren. Es gibt jetzt Alternativen zu einfachen statischen Funktionen, z. B. können Sie stattdessen Top-Level-Funktionen verwenden.

D3xter
quelle
7

Warum heißt es "Begleiter"?

Eine Objektdeklaration innerhalb einer Klasse kann mit dem Schlüsselwort Companion gekennzeichnet werden:

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

Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:

val instance = MyClass.create()

Wenn Sie nur 'Objekt' ohne 'Begleiter' verwenden, müssen Sie Folgendes tun:

val instance = MyClass.Factory.create()

Nach meinem Verständnis bedeutet "Begleiter", dass dieses Objekt ein Begleiter der äußeren Klasse ist.

Lyn
quelle
"Objekt" ohne "Begleiter" heißt so (MyClass (). create ()). Wie ein Singleton, aber um auf das Singleton-Objekt zugreifen zu können, müssen Sie zuerst die "äußere" Klasse initialisieren.
LiTTle
0

Wir können sagen, dass Companion der gleiche ist wie "Static Block" wie Java, aber im Fall von Kotlin gibt es kein Static Block-Konzept, als Companion in den Frame kommt.

So definieren Sie einen Begleitblock:

class Example {
      companion object {
        fun display(){
        //place your code
     }
  }
}

Aufrufmethode des Companion-Blocks, direkt mit Klassennamen

Example.Companion.display
Ankur Yadav
quelle