2016-07-14 127 views
82

Qual è il significato previsto di "oggetto companion"? Finora l'ho usato solo per sostituire Java static quando ne ho bisogno.Perché utilizziamo "oggetto associato" come una sorta di sostituzione dei campi statici Java in Kotlin?

Sono confuso con:

  • Perché si chiama "compagno"?
  • Significa che per creare più proprietà statiche, devo raggrupparlo nel blocco companion object?
  • immediatamente per generare un'istanza Singleton che è ambito a una classe, io scrivo spesso

:

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

che sembra un modo unidiomatic di farlo. Qual è il modo migliore?

risposta

64
  • Qual è il significato inteso di "oggetto associato"? Perché si chiama "compagno"?

    Innanzitutto, Kotlin non utilizza il concetto di Java static membri perché Kotlin ospita un concept of objects per descrivere le proprietà e funzioni connessi allo stato singoletto e Java static parte di una classe può essere elegantemente espressa in termini di singoletto : è un oggetto singleton che può essere chiamato dal nome della classe. Da qui la denominazione: è un oggetto che viene fornito con una classe.

    Il suo nome era class object and default object, ma poi it got renamed to companion object che è più chiaro ed è anche coerente con Scala companion objects.

    Oltre alla denominazione, è più potente di Java static membri: può estendere classi e interfacce, e puoi fare riferimento e passarlo come altri oggetti.

  • Significa che per creare più proprietà statiche, devo raggrupparlo nel blocco companion object?

    Sì, questo è il modo idiomatico. O si può anche dei gruppi hanno in oggetti non-compagno per il loro significato:

    class MyClass { 
        object IO { 
         fun makeSomethingWithIO() { /* ... */ } 
        } 
    
        object Factory { 
         fun createSomething() { /* ... */ } 
        } 
    } 
    
  • immediatamente per generare un'istanza Singleton che è ambito a una classe, io scrivo spesso /*...*/ che sembra un modo unidiomatic di fare esso. Qual è il modo migliore?

    Dipende da ciò che è necessario in ogni caso particolare. Il codice si adatta bene per l'archiviazione dello stato associato a una classe che viene inizializzata al primo richiamo.

    Se non ne hai bisogno per essere collegato con una classe, basta usare la dichiarazione oggetto:

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

    È inoltre possibile rimuovere lazy { ... } delegation per rendere la proprietà inizializzare sulla prima classe utilizzo, proprio come Java statico inizializzatori

    Potresti anche trovare modi utili di initializing singleton state.

+0

Esempi piacevoli e idiomatici. – Trein

13

Perché si chiama "compagno"?

Questo oggetto è un compagno delle istanze. IIRC c'era una lunga discussione qui: upcoming-change-class-objects-rethought

Vuol dire che per creare più proprietà statiche, devo gruppo insieme all'interno del blocco compagna oggetto?

Sì. Ogni proprietà/metodo "statico" deve essere inserito all'interno di questo compagno.

immediatamente per generare un'istanza Singleton che è ambito a una classe, io scrivo spesso

Non si costruisce l'istanza Singleton all'istante. Viene creato quando si accede a singleton per la prima volta.

che sembra un modo unidiomatico di farlo. Qual è il modo migliore?

Piuttosto andare con object Singleton { } per definire una classe singleton. Vedere: Object Declarations Lei non c'è bisogno di creare un'istanza di Singleton, basta usare in quel modo Singleton.doWork()

Basta tenere a mente che Kotlin offre altre cose per organizzare il codice. Esistono ora alternative a semplici funzioni statiche, ad es. potresti invece utilizzare le funzioni di primo livello.

0

Perché si chiama "compagno"?

Una dichiarazione oggetto all'interno di una classe possono essere contrassegnati con la parola chiave compagna:

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

membri dell'oggetto compagno possono essere chiamati utilizzando semplicemente il nome della classe come il qualificatore:

val instance = MyClass.create() 

Se si utilizza solo "oggetto" senza "companion", è necessario fare così:

val instance = MyClass.Factory.create() 

A mio parere, "compagno" indica che questo oggetto è compagno della classe esterna.