Kotlin From Scratch Classi e oggetti

Kotlin è un linguaggio di programmazione moderno che viene compilato in bytecode Java. È gratuito e open source e promette di rendere la codifica per Android ancora più divertente.  

Nell'articolo precedente, hai appreso usi avanzati di funzioni, come funzioni di estensione, chiusure, funzioni di ordine superiore e funzioni inline in Kotlin. 

In questo post riceverai un'introduzione alla programmazione orientata agli oggetti in Kotlin imparando a conoscere le classi: costruttori e proprietà, casting e funzioni di classe più avanzate che Kotlin semplifica. 

1. Classi

Una classe è un'unità di programma che raggruppa funzioni e dati per eseguire alcune attività correlate. Dichiariamo una classe in Kotlin usando il classe parola chiave simile a Java. 

libro di classe

Il codice precedente è la dichiarazione di classe più semplice: abbiamo appena creato una classe vuota chiamata Libro.  Possiamo ancora creare un'istanza di questa classe anche se non contiene un corpo che utilizza il suo costruttore predefinito.

val book = Libro ()

Come puoi osservare nel codice sopra, non abbiamo usato il nuovo parola chiave per creare un'istanza di questa classe, come di consueto in altri linguaggi di programmazione. nuovo non è una parola chiave in Kotlin. Questo rende conciso il nostro codice sorgente quando si crea un'istanza di classe. Ma sappi che l'istanziazione di una classe Kotlin in Java richiederà il nuovo parola chiave. 

// In un file Java Libro book = new Book ()

Costruttori e proprietà di classe

Diamo un'occhiata a come aggiungere un costruttore e proprietà alla nostra classe. Ma prima, vediamo una classe tipica in Java:

/ * Java * / public class Book private String title; privato lungo isbn; public Book (String title, Long isbn) this.title = title; questo.isbn = isbn;  public String getTitle () return title;  public void setTitle (String title) this.title = title;  public Long getIsbn () return isbn;  public void setIsbn (Long isbn) this.isbn = isbn; 

Guardando il nostro Libro modello di classe sopra, abbiamo il seguente:

  • due campi: titolo e isbn
  • un singolo costruttore
  • getter e setter per i due campi (fortunatamente IntelliJ IDEA può aiutarci a generare questi metodi)

Ora vediamo come possiamo scrivere il codice precedente in Kotlin invece:

/ * Kotlin * / class Book var title: String var isbn: long constructor (titolo: String, isbn: Long) this.title = title this.isbn = isbn

Una classe piuttosto ordinata! Ora abbiamo ridotto il numero di righe di codice da 20 a solo 9. costruttore() la funzione è chiamata a costruttore secondario in Kotlin. Questo costruttore è equivalente al costruttore Java che abbiamo chiamato durante l'istanziazione di una classe. 

In Kotlin, non esiste un concetto di campo come potrebbe esserne familiare; invece, utilizza il concetto di "proprietà". Ad esempio, abbiamo due proprietà mutabili (lettura-scrittura) dichiarate con var parola chiave: titolo e isbn nel Libro classe. (Se hai bisogno di un aggiornamento sulle variabili in Kotlin, visita gentilmente il primo post di questa serie: Variabili, Tipi di base e matrici). 

Una cosa sorprendente è che i getter e setter per queste proprietà vengono generati automaticamente dal compilatore Kotlin. Si noti che non abbiamo specificato alcun modificatore di visibilità per queste proprietà, quindi per impostazione predefinita sono pubbliche. In altre parole, è possibile accedervi da qualsiasi luogo.

Diamo un'occhiata a un'altra versione della stessa classe in Kotlin:

costruttore di class book (titolo: String, isbn: Long) var title: String var isbn: Long init this.title = title this.isbn = isbn

In questo codice, abbiamo rimosso il costruttore secondario. Invece, abbiamo dichiarato un costruttore nell'intestazione della classe chiamata a costruttore principale. Un costruttore principale non ha spazio per mettere un blocco di codice, quindi utilizziamo il dentro modificatore per inizializzare i parametri in entrata dal costruttore principale. Si noti che il dentro il blocco di codice viene eseguito immediatamente quando viene creata l'istanza di classe.

Come puoi vedere, il nostro codice ha ancora molto standard. Riduciamolo ulteriormente:

costruttore di class book (var title: String, var isbn: Long)

Nostro Libro la classe ora è solo una riga di codice. È davvero fantastico! Si noti che nella lista dei parametri del costruttore principale, abbiamo definito le nostre proprietà mutabili: titolo e isbn direttamente all'interno del costruttore principale con il var parola chiave. 

Possiamo inoltre aggiungere valori predefiniti a qualsiasi proprietà di classe direttamente all'interno del costruttore.

costruttore di class book (var title: String = "valore predefinito", var isbn: Long)

In effetti, possiamo anche omettere il costruttore parola chiave, ma solo se non ha alcun modificatore di visibilità (pubblico, privato, o protetta) o eventuali annotazioni. 

class Book (var title: String = "valore predefinito", var isbn: Long)

Una lezione molto bella, devo dire!

Ora possiamo creare un'istanza di classe come questa:

val book = Book ("Una canzone di ghiaccio e fuoco", 9780007477159) val book2 = Book (1234) // usa il valore predefinito della proprietà del titolo

Accesso e impostazione delle proprietà 

In Kotlin, possiamo ottenere una proprietà dall'oggetto classe libro, seguito da un separatore di punti ., quindi il nome della proprietà titolo. Viene chiamato questo stile conciso di accesso alle proprietà sintassi di accesso alle proprietà. In altre parole, non dobbiamo chiamare il metodo getter della proprietà per accedere o chiamare il setter per impostare una proprietà in Kotlin, come facciamo in Java. 

println (book.title) // "Una canzone di ghiaccio e fuoco"

Perché il isbn la proprietà è dichiarata con il var parola chiave (lettura-scrittura), possiamo anche modificare il valore della proprietà usando l'operatore di assegnazione =.

book.isbn = 1234 println (book.isbn) // 1234

Vediamo un altro esempio:

class Book (var title: String, val isbn: Long) val book = Libro ("Una canzone di ghiaccio e fuoco", 9780007477159) book.isbn = 1234 // errore: proprietà di sola lettura book.title = "Le cose cadono a pezzi "// titolo riassegnato con valore

Qui, abbiamo aggiornato il isbn parametro per essere immutabile (sola lettura) invece - usando il val parola chiave. Abbiamo istanziato un'istanza di classe libro e riassegnato il titolo proprietà il valore "Things Fall Apart". Si noti che quando abbiamo provato a riassegnare il isbn valore della proprietà a 1234, il compilatore si è lamentato. Questo perché la proprietà è immutabile, essendo stata definita con il val parola chiave. 

Interoperabilità Java

Essere consapevoli che dichiarando un parametro con il var modificatore all'interno del costruttore principale, il compilatore Kotlin (dietro le quinte) ci ha aiutato a generare entrambi gli accessor di proprietà: getter e setter. Se usi val, genererà solo il getter. 

/ * Kotlin * / class Book (var title: String, val isbn: Long)

Ciò significa che i chiamanti Java possono semplicemente ottenere o impostare il campo proprietà chiamando rispettivamente il setter o il metodo getter della proprietà. Ricorda, questo dipende dal modificatore usato per definire la proprietà di Kotlin: var o val

/ * Java * / Book book = new Book ("Una canzone di ghiaccio e fuoco", 9780385474542) println (book.getTitle ()) // "Una canzone di ghiaccio e fuoco" book.setTitle ("Things Fall Apart") // imposta un nuovo valore println (book.getTitle ()) // "Things Fall Apart" book.getIsbn () // 9780385474542 book.setIsbn (4545454) // non verrà compilato

Getter e setter personalizzati

In questa sezione, ti mostrerò come creare accessor personalizzati (getter e setter) per una proprietà in Kotlin, se lo desideri. La creazione di un setter personalizzato può essere utile se si desidera convalidare o verificare un valore prima che sia impostato su una proprietà di classe. E un getter di proprietà personalizzato può essere utile quando si desidera modificare o modificare il valore che deve essere restituito.  

Creazione di un setter personalizzato

Poiché vogliamo creare il nostro getter o setter personalizzato per una proprietà, dobbiamo definire quella proprietà nel corpo della classe anziché l'intestazione del costruttore. 

class Book (val isbn: Long) var title = "valore predefinito"

Questo è il motivo per cui abbiamo spostato il mutabile (lettura-scrittura) titolo proprietà nel corpo della classe e gli ha dato un valore predefinito (altrimenti non sarebbe compilato).  

class Book (val isbn: Long) var title = "valore predefinito" set (valore) if (! value.isNotEmpty ()) throw IllegalArgumentException ("Il titolo non deve essere vuoto") campo = valore

Puoi vedere che abbiamo definito il nostro metodo di setter valore impostato) per il titolo proprio sotto la definizione della proprietà, nota che non è possibile modificarlo impostato() firma del metodo perché questo è ciò che il compilatore si aspetta come funzione di settaggio della proprietà personalizzata.

Il parametro valore passato al impostato metodo rappresenta il valore effettivo che è stato assegnato alla proprietà dagli utenti: è possibile modificare il nome del parametro se lo si desidera, ma valore è molto preferito Abbiamo convalidato il valore controllando se il valore è vuoto. Se vuoto, interrompi l'esecuzione e genera un'eccezione; altrimenti, riassegna il valore a uno speciale campo variabile.

Questo speciale campo campo variabile all'interno del impostato metodo è un alias per il campo di supporto della proprietà: un campo di supporto è solo un campo che viene utilizzato dalle proprietà quando si desidera modificare o utilizzare tali dati di campo. diversamente da valore, non puoi rinominare questo speciale campo variabile.

Creazione di un Getter personalizzato

È molto facile creare un getter personalizzato per una proprietà in Kotlin. 

class Book (val isbn: Long) var title = "valore predefinito" // ... set metodo get () return field.toUpperCase ()

Dentro il ottenere metodo, semplicemente restituiamo una modifica campo-nel nostro caso, abbiamo restituito il titolo del libro in maiuscolo. 

val book = Libro (9780007477159) book.title = "Una canzone di ghiaccio e fuoco" println (book.title) // "UN CANTO DI GHIACCIO E FUOCO" println (book.isbn) // 9780007477159

Si noti che ogni volta che impostiamo un valore su titolo proprietà, è impostato il blocco di metodo viene eseguito, lo stesso vale per il ottenere metodo ogni volta che lo recuperiamo. 

Se vuoi conoscere le funzioni dei membri per una classe Kotlin (il tipo di funzione che è definita all'interno di una classe, oggetto o interfaccia), visita il post More Fun With Functions in questa serie. 

Altro su Costruttori

Come ho discusso in precedenza, abbiamo due tipi di costruttori in Kotlin: primario e secondario. Abbiamo la possibilità di combinare entrambi in una singola classe, come puoi vedere nell'esempio seguente:

class Car (nome val: String, val plateNo: String) var new: Boolean = true constructor (nome: String, plateNo: String, new: Boolean): this (name, plateNo) this.new = new

Si noti che non possiamo dichiarare le proprietà all'interno di un costruttore secondario, come abbiamo fatto per il costruttore principale. Se vogliamo farlo, dobbiamo dichiararlo all'interno del corpo della classe e quindi inizializzarlo nel costruttore secondario.  

Nel codice sopra, impostiamo il valore predefinito di nuovo proprietà per la classe Auto (ricorda, nuovo non è una parola chiave in Kotlin), possiamo quindi utilizzare il costruttore secondario per cambiarlo se vogliamo. In Kotlin, ogni costruttore secondario deve chiamare il costruttore principale o chiamare un altro costruttore secondario che chiama il costruttore principale: utilizziamo il Questo parola chiave per raggiungerlo. 

Si noti inoltre che possiamo avere più costruttori secondari all'interno di una classe. 

class car (nome val: String, val plateNo: String) var new: Boolean? = null var color: String = "" costruttore (nome: String, plateNo: String, new: Boolean): questo (name, plateNo) this.new = new costruttore (nome: String, plateNo: String, new: Boolean , color: String): this (name, plateNo, new) this.colour = color

Se una classe estende una superclasse, allora possiamo usare il super parola chiave (simile a Java) per chiamare il costruttore della superclasse (discuteremo dell'ereditarietà di Kotlin in un post futuro). 

// chiama direttamente costruttore principale val car1 = Car ("Peugeot 504", "XYZ234") // chiama direttamente 1st sec. constructor val car2 = Car ("Peugeot 504", "XYZ234", false) // chiama direttamente l'ultimo secondo. costruttore val car3 = Car ("Peugeot 504", "XYZ234", falso, "grigio") 

Come ho detto prima, per noi includere esplicitamente un modificatore di visibilità per un costruttore in una classe, dobbiamo includere il costruttore parola chiave: per impostazione predefinita, i costruttori sono pubblici. 

costruttore privato di classe Car (nome: String, val plateNo: String) // ... 

Qui, abbiamo reso privato il costruttore: ciò significa che gli utenti non possono creare un'istanza di un oggetto utilizzando direttamente il suo costruttore. Questo può essere utile se si desidera che gli utenti chiamino un altro metodo (un metodo factory) per creare indirettamente gli oggetti. 

2. Qualsiasi e niente tipi

In Kotlin, viene chiamato il tipo più in alto nella gerarchia dei tipi Qualunque. Questo è equivalente a Java Oggetto genere. Ciò significa che tutte le classi in Kotlin ereditano esplicitamente dal Qualunque tipo, incluso StringaInt, Doppio, e così via. Il Qualunque tipo contiene tre metodi: è uguale aaccordare, e codice hash

Possiamo anche utilizzare il Niente classe in Kotlin in funzioni che restituiscono sempre un'eccezione, in altre parole, per le funzioni che non terminano normalmente. Quando una funzione ritorna Niente, allora sappiamo che farà un'eccezione. Nessun tipo equivalente di questo tipo esiste in Java. 

fun throwException (): Nothing throw Exception ("messaggio di eccezione)

Questo può tornare utile quando si verifica un comportamento di gestione degli errori nei test delle unità.   

3. Modificatori di visibilità

I modificatori di visibilità ci aiutano a limitare l'accessibilità della nostra API al pubblico. Possiamo fornire diversi modificatori di visibilità alle nostre classi, interfacce, oggetti, metodi o proprietà. Kotlin ci fornisce quattro modificatori di visibilità:

Pubblico

Questa è l'impostazione predefinita e qualsiasi classe, funzione, proprietà, interfaccia o oggetto a cui è possibile accedere con questo modificatore da qualsiasi posizione.

Privato 

Una funzione, un'interfaccia o una classe di livello superiore dichiarata come privato è possibile accedere solo all'interno dello stesso file. 

Qualsiasi funzione o proprietà dichiarata privato all'interno di una classe, oggetto o interfaccia possono essere visibili solo ad altri membri della stessa classe, oggetto o interfaccia. 

class Account importo val privato: Double = 0.0

protetta

Il protetta il modificatore può essere applicato solo a proprietà o funzioni all'interno di una classe, oggetto o interfaccia; non può essere applicato a funzioni, classi o interfacce di primo livello. Proprietà o funzioni con questo modificatore sono accessibili solo all'interno della classe che lo definisce e in ogni sottoclasse. 

Interno 

In un progetto che ha un modulo (Gradle o modulo Maven), una classe, oggetto, interfaccia o funzione specificata con interno il modificatore dichiarato all'interno di quel modulo è accessibile solo da quel modulo. 

Conto interno classe importo importo: doppio = 0,0

4. Smart Casting

Casting significa prendere un oggetto di un altro tipo e convertirlo in un altro tipo di oggetto. Ad esempio, in Java, usiamo il instanceof operatore per determinare se un particolare tipo di oggetto è di un altro tipo prima di lanciarlo.

/ * Java * / if (shape instanceof Circle) Circle circle = (Circle) shape; circle.calCircumference (3.5); 

Come puoi vedere, abbiamo controllato se forma l'istanza è Cerchio, e quindi dobbiamo lanciare esplicitamente il forma riferimento a a Cerchio digita in modo tale che possiamo chiamare i metodi di cerchio genere. 

Un'altra cosa meravigliosa di Kotlin è l'intelligenza del suo compilatore quando si parla di casting. Vediamo ora una versione in Kotlin.

/ * Kotlin * / if (shape is Circle) shape.calCircumference (3.5)

Piuttosto pulito! Il compilatore è intelligente nel sapere che il Se il blocco verrà eseguito solo se il forma oggetto è un'istanza di Cerchio-quindi il meccanismo di fusione è fatto sotto il cofano per noi. Ora possiamo facilmente chiamare proprietà o funzioni di Cerchio digitare dentro il Se bloccare. 

if (shape is Circle && shape.hasRadius ()) println ("Il raggio del cerchio è shape.radius")

Qui, l'ultima condizione dopo il && nel Se l'intestazione verrà chiamata solo quando la prima condizione è vero. Se la forma non è un Cerchio, allora l'ultima condizione non sarà valutata. 

5. Casting esplicito

Possiamo usare il come operatore (o cast non sicuro operatore) per trasmettere esplicitamente un riferimento di un tipo a un altro tipo in Kotlin. 

val circle = forma come Circle circle.calCircumference (4)

Se l'operazione di trasmissione esplicita è illegale, nota che a ClassCastException sarà lanciato. Per evitare che venga lanciata un'eccezione durante il casting, possiamo usare il cast sicuro operatore (o operatore di cast nullable) come?

val circle: Circle? = forma come? Cerchio

Il come? l'operatore proverà a trasmettere al tipo desiderato e restituirà nullo se il valore non può essere lanciato invece di generare un'eccezione. Ricorda che un meccanismo simile è stato discusso nella sezione Nullability in Nullability, Loops e Condizioni post in questa serie. Leggi lì per un aggiornamento.

6. Gli oggetti

Gli oggetti in Kotlin sono più simili agli oggetti JavaScript rispetto agli oggetti Java. Nota che un oggetto in Kotlin non è un'istanza di una classe specifica!

Gli oggetti sono molto simili alle classi. Ecco alcune delle caratteristiche degli oggetti in Kotlin:

  • Possono avere proprietà, metodi e un dentro bloccare.
  • Queste proprietà o metodi possono avere modificatori di visibilità.
  • Non possono avere costruttori (primari o secondari).
  • Possono estendere altre classi o implementare un'interfaccia.

Scopriamo ora come creare un oggetto.  

oggetto Singleton fun myFunc (): Unit // do something

Inseriamo il oggetto parola chiave prima del nome dell'oggetto che vogliamo creare. In effetti, stiamo creando dei singleton quando creiamo oggetti in Kotlin usando il oggetto costrutto, perché esiste solo un'istanza di un oggetto. Imparerai di più su questo argomento quando discuteremo dell'interoperabilità degli oggetti con Java. 

Un singleton è un modello di progettazione software che garantisce che una classe abbia solo un'istanza e che tale classe fornisca un punto di accesso globale. Ogni volta che più classi o client richiedono la classe, ottengono la stessa istanza della classe. È possibile controllare il mio post sul modello singleton in Java per saperne di più.

È possibile accedere all'oggetto o singleton in qualsiasi punto del progetto, a condizione che si importi il ​​pacchetto. 

Singleton.myFunc ()

Se sei un programmatore Java, questo è il modo in cui tipicamente creiamo singleton:

public class Singleton private static Singleton INSTANCE = null; // altre variabili di istanza possono essere qui private Singleton () ; pubblico statico sincronizzato Singleton getInstance () if (INSTANCE == null) INSTANCE = new Singleton ();  return (INSTANCE);  // altri metodi di istanza possono seguire

Come puoi vedere, usa il Kotlin oggetto costrutto lo rende conciso e più facile da creare singleton. 

Gli oggetti in Kotlin possono essere utilizzati anche per creare costanti. Tipicamente in Java, creiamo costanti in una classe rendendola un campo finale statico pubblico come questo:

public final class APIConstants public static final String baseUrl = "http://www.myapi.com/"; APIConstants privati ​​() 

Questo codice in Java può essere convertito in Kotlin in modo più succinto come questo:

pacchetto com.chike.kotlin.constants object APIConstants val baseUrl: String = "http://www.myapi.com/"

Qui abbiamo dichiarato la costante APIConstants con una proprietà baseurl all'interno di un pacchetto com.chike.kotlin.constants. Sotto il cofano, un membro finale statico privato di Java baseurl viene creato per noi e inizializzato con l'URL della stringa. 

Per usare questa costante in un altro pacchetto in Kotlin, importa semplicemente il pacchetto.

import com.chike.kotlin.constants.APIConstants APIConstants.baseUrl

Interoperabilità Java

Kotlin converte un oggetto in una classe Java finale sotto il cofano. Questa classe ha un campo statico privato ESEMPIO che contiene una singola istanza (un singleton) della classe. Il codice seguente mostra come gli utenti possano semplicemente chiamare un oggetto Kotlin da Java. 

/ * Java * / Singleton.INSTANCE.myFunc ()

Qui, una classe Java chiamata Singleton è stato generato con un membro finale statico pubblico ESEMPIO, compresa una funzione pubblica finale myFunc ().

Per rendere la funzione o la proprietà dell'oggetto in Kotlin essere un membro statico della classe Java generata, usiamo il comando @JvmStatic annotazione. Ecco come usarlo:

object Singleton @JvmStatic fun myFunc (): Unit // do something

Applicando il @JvmStatic annotazione a myFunc (), il compilatore lo ha trasformato in una funzione statica. 

Ora i chiamanti Java possono chiamarlo come una normale chiamata membro statica. Si noti che utilizzando il ESEMPIO il campo statico per chiamare i membri continuerà a funzionare.

/ * Java * / Singleton.myFunc ()

7. Oggetti Companion

Ora dobbiamo capire quali oggetti ci sono in Kotlin, tuffiamoci in un altro tipo di oggetti chiamati oggetti complementari. 

Poiché Kotlin non supporta classi, metodi o proprietà statiche come quelle che abbiamo in Java, il team di Kotlin ci ha fornito un'alternativa più potente chiamata oggetti complementari. Un oggetto companion è fondamentalmente un oggetto che appartiene a una classe: questa classe è nota come classe companion dell'oggetto. Ciò significa anche che le caratteristiche che ho citato per gli oggetti si applicano anche agli oggetti complementari. 

Creazione di un oggetto companion

Analogamente ai metodi statici in Java, un oggetto companion non è associato a un'istanza di classe ma piuttosto alla classe stessa, ad esempio un metodo statico di fabbrica, che ha il compito di creare un'istanza di classe. 

class Person private constructor (var firstName: String, var lastName: String) oggetto companion fun create (firstName: String, lastName: String): Person = Person (firstName, lastName)

Qui, abbiamo creato il costruttore privato-questo significa che gli utenti esterni alla classe non possono creare direttamente un'istanza. All'interno del nostro blocco oggetto companion, abbiamo una funzione creare(), che crea a Persona oggetto e lo restituisce. 

Richiamo di una funzione oggetto companion

compagno l'istanziazione degli oggetti è pigra. In altre parole, verrà istanziato solo quando necessario la prima volta. L'istanziazione di a compagno oggetto si verifica quando un'istanza del compagno classe è stata creata o il compagno si accede ai membri dell'oggetto. 

Vediamo come richiamare una funzione oggetto companion in Kotlin.

val person = Person.create ("Cersei", "Lannister") println (person.firstName) // stampa "Cersei"

Come puoi vedere, è come invocare un metodo statico in Java normalmente. In altre parole, chiamiamo semplicemente la classe e poi chiamiamo il membro. Nota che oltre alle funzioni, possiamo anche avere proprietà all'interno del nostro oggetto compagno. 

class Person private constructor (var firstName: String, var lastName: String) init count ++ oggetto associato var count: Int = 0 fun create (firstName: String, lastName: String): Person = Person (firstName, lastName) init println ("Oggetto compagno persona creato")

Nota anche che il compagno la classe ha accesso illimitato a tutte le proprietà e funzioni dichiarate nel suo oggetto compagno, mentre un oggetto compagno non può accedere ai membri della classe. Possiamo avere un dentro blocco di codice all'interno di a compagno oggetto: questo viene chiamato immediatamente quando viene creato l'oggetto companion. 

Person.create ("Arya", "Stark") Person.create ("Daenerys", "Targaryen") println (Person.count)

Il risultato dell'esecuzione del codice sopra sarà: 

Oggetto compagno persona creato 2

Ricorda, solo una singola istanza di una classe compagno l'oggetto può mai esistere. 

Siamo anche liberi di fornire al nostro oggetto associato un nome. 

// ... oggetto associato Factory var count: Int = 0 fun create (firstName: String, lastName: String): Person = Person (firstName, lastName) // ... 

Qui, gli abbiamo dato un nome chiamato Fabbrica. Possiamo quindi chiamarlo così in Kotlin:

Person.Factory.create ("Petyr", "Baelish")

Questo stile è prolisso, quindi è molto preferibile attenersi al modo precedente. Ma questo potrebbe tornare utile quando si chiama una funzione o una proprietà dell'oggetto companion da Java.

Come ho detto prima, come gli oggetti, gli oggetti companion possono anche includere proprietà o funzioni, implementare interfacce e persino estendere una classe. 

interfaccia PersonFactory fun create (firstName: String, lastName: String): Person class Persona private constructor (var firstName: String, var lastName: String) oggetto companion: PersonFactory override fun create (firstName: String, lastName: String) : Person return Person (firstName, lastName)

Qui, abbiamo un'interfaccia PersonFactory con solo un singolo creare() funzione. Guardando il nostro nuovo modificato compagno oggetto, ora implementa questa interfaccia (imparerai a conoscere le interfacce e l'ereditarietà di Kotlin in un post successivo). 

Interoperabilità Java

Sotto il cofano, gli oggetti complementari vengono compilati in modo simile al modo in cui viene compilato un oggetto Kotlin. Nel nostro caso, vengono generate due classi: una finale Persona classe e una classe finale statica interna Persona $ Companion

Il Persona la classe contiene un membro statico finale chiamato Compagno-questo campo statico è un oggetto di Persona $ Companion classe interiore. Il Persona $ Companion la classe interna ha anche i suoi membri, e uno di loro è una funzione pubblica finale chiamata creare()

Nota che non abbiamo dato un nome al nostro oggetto companion, quindi la classe interna statica generata era Compagno. Se avessimo dato un nome, il nome generato sarebbe il nome che abbiamo dato a Kotlin. 

/ * Java * / Person person = Person.Companion.create ("Jon", "Snow"); 

Qui, l'oggetto associato in Kotlin non ha nome, quindi usiamo il nome Compagno fornito dal compilatore per i chiamanti Java per chiamarlo.

Il @JvmStatic l'annotazione applicata a un membro dell'oggetto compagno funziona in modo simile a come funziona per un oggetto normale. 

Companion Object Extensions

Analogamente a come le funzioni di estensione possono estendere la funzionalità di una classe, possiamo anche estendere la funzionalità di un oggetto associato. (Se vuoi un aggiornamento sulle funzioni di estensione in Kotlin, visita il tutorial sulle funzioni avanzate in questa serie). 

class ClassA companion object  fun ClassA.Companion.extFunc () // ... do implementation ClassA.extFunc ()

Qui, abbiamo definito una funzione di estensione extFunc () sull'oggetto compagno ClassA.Companion. In altre parole, extfunc () è un'estensione dell'oggetto associato. Quindi possiamo chiamare l'estensione come se fosse una funzione membro (non lo è!) Dell'oggetto associato. 

Dietro le quinte, il compilatore creerà una funzione di utilità statica extFunc (). L'oggetto ricevitore come argomento per questa funzione di utilità è ClasseA $ Companion

Conclusione

In questo tutorial, hai imparato a conoscere classi e oggetti di base in Kotlin. Di seguito abbiamo trattato le seguenti lezioni:

  • creazione di classe
  • costruttori
  • proprietà
  • modificatori di visibilità
  • casting intelligente
  • casting esplicito 

Inoltre, hai appreso come gli oggetti e gli oggetti complementari in Kotlin possono facilmente sostituire i metodi statici, le costanti e i singleton codificati in Java. Ma non è tutto! C'è ancora molto da imparare sulle classi di Kotlin. Nel prossimo post, ti mostrerò ancora più interessanti funzionalità di Kotlin per la programmazione orientata agli oggetti. A presto!

Per saperne di più sulla lingua di Kotlin, ti consiglio di visitare la documentazione di Kotlin. Oppure guarda alcuni dei nostri altri post di sviluppo di app per Android qui su Envato Tuts+!