Kotlin de la zero clase și obiecte

Kotlin este un limbaj de programare modern care se compilează la Java bytecode. Este gratuit și open source, și promite să facă codificarea pentru Android chiar mai distractiv.  

În articolul precedent, ați învățat utilizări avansate ale funcțiilor, cum ar fi funcții de extensie, închideri, funcții de ordin superior și funcții inline în Kotlin. 

În acest post veți primi o introducere în programarea orientată pe obiecte în Kotlin, învățând despre clase: constructori și proprietăți, turnare și caracteristici mai avansate de clasă pe care Kotlin le face ușor. 

1. Clase

O clasă este o unitate de program care grupează funcții și date pentru a efectua anumite sarcini conexe. Declarăm o clasă la Kotlin folosind clasă cuvânt-cheie similar cu Java. 

clasa de carte

Codul precedent este cea mai simplă declarație de clasă - tocmai am creat o clasă goală numită Carte.  Încă putem instantiza această clasă, chiar dacă nu conține un corp folosind constructorul implicit.

carte val = Carte ()

După cum puteți observa în codul de mai sus, nu am folosit nou cuvânt cheie pentru a instanțiate această clasă - așa cum este de obicei în alte limbi de programare. nou nu este un cuvânt cheie în Kotlin. Acest lucru face ca codul sursă să fie concis la crearea unei instanțe de clasă. Dar fiți conștienți de faptul că instanțiarea unei clase Kotlin în Java va necesita nou cuvinte cheie. 

// într-un fișier Java Carte de carte = carte nouă ()

Constructori de clasă și proprietăți

Să examinăm cum să adăugăm un constructor și proprietăți clasei noastre. Dar mai întâi, să vedem o clasă tipică în Java:

/ * Java * / clasa publica Cartea nume String privat; privat Long isbn; cartea publică (titlul șirului, Long isbn) this.title = title; this.isbn = isbn;  public String getTitle () return title;  public void setTitle (titlu șir) this.title = title;  public lung getIsbn () return isbn;  public void setIsbn (lung isbn) this.isbn = isbn; 

Privind la noi Carte clasa de modele de mai sus, avem urmatoarele:

  • două câmpuri: titlu și isbn
  • un singur constructor
  • getters și setters pentru cele două câmpuri (din fericire, IntelliJ IDEA ne poate ajuta să generăm aceste metode)

Acum, să ne uităm la modul în care putem scrie codul precedent în Kotlin:

/ * Kotlin * / clasa Cărții var titlu: String var isbn: Constructor lung (titlu: String, isbn: Long) this.title = title this.isbn = isbn

O clasă destul de ordonată! Am redus acum numărul de linii de cod de la 20 la 9 constructor() funcția este numită a constructor secundar în Kotlin. Acest constructor este echivalent cu constructorul Java pe care l-am sunat când instanțiam o clasă. 

În Kotlin, nu există niciun concept de câmp cum ar fi să fiți familiarizați; în schimb, utilizează conceptul de "proprietăți". De exemplu, avem două proprietăți mutabile (citire-scriere) declarate cu var cuvinte cheie: titlu și isbn în Carte clasă. (Dacă aveți nevoie de o actualizare a variabilelor în Kotlin, vizitați primul post din această serie: Variabile, Tipuri de bază și Arrays). 

Un lucru uimitor este faptul că getters și setters pentru aceste proprietăți sunt generate automat pentru noi sub capotă de compilatorul Kotlin. Observați că nu am specificat niciun modificator de vizibilitate pentru aceste proprietăți - în mod implicit, ele sunt publice. Cu alte cuvinte, ele pot fi accesate de oriunde.

Să ne uităm la o altă versiune a aceleiași clase în Kotlin:

constructor de carte (titlul: String, isbn: Long) var titlu: String var isbn: Long init this.title = title this.isbn = isbn

În acest cod, am eliminat constructorul secundar. În schimb, am declarat un constructor în antetul de clasă denumit a constructor primar. Un constructor primar nu are niciun loc pentru a pune un bloc de cod, deci folosim init modificator pentru a inițializa parametrii de intrare de la constructorul principal. Rețineți că init blocul de coduri este executat imediat atunci când instanța de clasă este creată.

După cum puteți vedea, codul nostru are încă o mulțime de caractere. Să o reducem mai mult:

clasa Constructor de carte (titlul var: String, var isbn: Long)

Al nostru Carte clasa este acum doar o linie de cod. Este foarte cool! Observați că în lista parametrilor constructori primari am definit proprietățile noastre mutabile: titlu și isbn direct în interiorul constructorului principal cu var cuvinte cheie. 

De asemenea, putem adăuga valori implicite pentru oricare din proprietățile clasei din interiorul constructorului.

clasa constructor de carte (titlul var: String = "valoare implicită", var isbn: Long)

De fapt, putem, de asemenea, să omitem constructor , dar numai dacă nu are modificator de vizibilitate (public, privat, sau protejat) sau orice adnotări. 

clasa de carte (titlul var: String = "valoarea implicită", var isbn: Long)

O clasă foarte curată, trebuie să spun!

Acum putem crea o instanță de clasă astfel:

val book = Book ("Un cântec de gheață și foc", 9780007477159) val book2 = Book (1234) // utilizează valoarea implicită a proprietății titlu

Accesarea și setarea proprietăților 

În Kotlin, putem obține o proprietate de obiectul de clasă carte, urmată de un separator de puncte ., apoi numele de proprietate titlu. Acest stil concis de accesare a proprietăților se numește proprietate sintaxă de acces. Cu alte cuvinte, nu trebuie să apelăm metoda getter-ului de proprietate pentru a accesa sau a apela setter-ul pentru a seta o proprietate în Kotlin - așa cum facem în Java. 

println (book.title) // "Un cântec de gheață și foc"

Deoarece isbn proprietatea este declarată cu var cuvânt cheie (citire-scriere), putem modifica, de asemenea, valoarea proprietății folosind operatorul de atribuire =.

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

Să vedem un alt exemplu:

clasa de carte (titlul var: String, val isbn: Long) val carte = Rezervați ("Un cântec de gheață și foc", 9780007477159) book.isbn = 1234 // eroare: read-only property book.title = "Things Fall Apart "/ / reassigned titlu cu valoare

Aici am actualizat isbn parametru pentru a fi imuabil (în schimb, numai pentru citire) - utilizând Val cuvinte cheie. Am instanțiat o instanță de clasă carte și a reatribuit titlu proprietatea valoarea "Lucrurile se încadrează în afara". Observați că atunci când am încercat să îl redistribuim isbn valoarea de proprietate la 1234, compilatorul sa plâns. Acest lucru se datorează faptului că proprietatea este imuabilă, fiind definită cu Val cuvinte cheie. 

Interoperabilitate Java

Rețineți că prin declararea unui parametru cu var modificator din cadrul constructorului principal, compilatorul Kotlin (în spatele scenei) ne-a ajutat să generăm atât accesoriile de proprietate: getter și setter. Dacă utilizați Val, aceasta va genera numai getter-ul. 

/ * Kotlin * / clasa de carte (titlul var: String, val isbn: Long)

Aceasta înseamnă că apelanții Java pot pur și simplu să obțină sau să stabilească câmpul de proprietate apelând setterul sau metoda getter a proprietății. Rețineți că aceasta depinde de modificatorul utilizat pentru a defini proprietatea Kotlin: var sau Val

/ * Java * / carte de carte = carte nouă ("Un cântec de gheață și foc", 9780385474542) println (book.getTitle ()) // book.setTitle ("Things Fall Apart" // stabilește o nouă valoare println (book.getTitle ()) // "Things Fall Apart" book.getIsbn () // 9780385474542 book.setIsbn (4545454) // nu va compila

Obtinerea personalizata si setterii

În această secțiune, vă vom arăta cum să creați accesori personalizați (getters și setters) pentru o proprietate în Kotlin, dacă doriți. Crearea unui setter personalizat poate fi utilă dacă doriți să validați sau să verificați o valoare înainte de a fi setată la o proprietate a clasei. Și un achiziționator de proprietate personalizată poate fi util atunci când doriți să modificați sau să modificați valoarea care trebuie returnată.  

Crearea unui setter personalizat

Pentru că vrem să creăm propriul nostru getter sau setter personalizat pentru o proprietate, trebuie să definim acea proprietate în corpul clasei în locul antetului constructorului. 

Cartea de clasă (val isbn: Long) var title = "valoare implicită"

De aceea am mutat textul mutable (read-write) titlu proprietate în corpul clasei și i-a dat o valoare implicită (sau altfel nu s-ar compila).  

(val) este valabil (val este): var title = "valoare prestabilită" setată (valoare) if (! value.isNotEmpty ())

Puteți vedea că am definit propria noastră metodă de setare set (valoare) pentru titlu chiar sub definiția proprietății - rețineți că nu puteți modifica acest lucru a stabilit() metoda de semnătură, deoarece aceasta este ceea ce compilatorul se așteaptă ca o funcție setter proprietate personalizată.

Parametrul valoare trecut la a stabilit reprezintă valoarea reală care a fost atribuită proprietarului de către utilizatori - puteți modifica numele parametrului dacă doriți, dar valoare este mult preferat. Am validat valoare verificând dacă valoarea este goală. Dacă este gol, opriți executarea și aruncați o excepție; altfel, realocați valoarea la o valoare specială camp variabil.

Acest lucru special camp câmpul variabil în interiorul a stabilit metoda este un alias pentru câmpul de susținere al proprietății - un câmp de asistență este doar un câmp care este utilizat de proprietăți atunci când doriți să modificați sau să utilizați acele date din câmp. Spre deosebire de valoare, nu puteți redenumi acest lucru special camp variabil.

Crearea unui Getter personalizat

Este foarte ușor să creați un achiziționator personalizat pentru o proprietate în Kotlin. 

Clasa de valori (val isbn: Long) var title = "valoare implicită" // ... set method get () return field.toUpperCase ()

În interiorul obține metoda, vom returna pur și simplu o modificare camp-în cazul nostru, am întors titlul cărții în majuscule. 

cartea de carte = cartea (9780007477159) book.title = "Un cântec de gheață și foc" println (book.title) // "UN SONG DE ICE ȘI FIRE" println (book.isbn) // 9780007477159

Rețineți că de fiecare dată când setăm o valoare la titlu proprietățile sale a stabilit blocul de metode este executat - același lucru este valabil și pentru obține de fiecare dată când îl preluăm. 

Dacă doriți să aflați despre funcțiile membrilor pentru o clasă Kotlin (tipul de funcție definit în interiorul unei clase, a unui obiect sau a unei interfețe), vizitați postul More Fun With Functions din această serie. 

Mai multe despre Constructori

Așa cum am discutat mai devreme, avem două tipuri de constructori în Kotlin: primar și secundar. Avem libertatea de a combina amândouă într-o singură clasă - după cum puteți vedea în exemplul de mai jos:

(nume: String, val platNot: String) var nou: Boolean = constructor adevărat (nume: String, plateNo: String, nou: boolean): this (name, plateNo) this.new = new

Rețineți că nu putem declara proprietăți în interiorul unui constructor secundar, așa cum am făcut-o pentru constructorul principal. Dacă vrem să facem acest lucru, trebuie să îl declarăm în corpul clasei și apoi să îl inițializăm în constructorul secundar.  

În codul de mai sus, setăm valoarea implicită pentru nou proprietate pentru clasă Mașină (tine minte, nou nu este un cuvânt cheie în Kotlin) - putem folosi apoi constructorul secundar pentru ao schimba dacă vrem. În Kotlin, fiecare constructor secundar trebuie să apeleze constructorul primar sau să apeleze un alt constructor secundar care sună constructorul primar - folosim acest cuvânt cheie pentru a obține acest lucru. 

Rețineți, de asemenea, că putem avea mai mulți constructori secundari într-o clasă. 

clasa Mașină (nume val: String, val plateNo: String) var nou: Boolean? = null var color: String = "" constructor (nume: String, plateNo: String, new: boolean): this (name, plateNo) this.new = new constructor , culoare: String): aceasta (nume, placNu, nou) this.colour = color

Dacă o clasă extinde o superclasă, atunci putem folosi super (similar cu Java) pentru a apela constructorul superclasei (vom discuta moștenirea în Kotlin într-un post viitor). 

// solicită direct constructorul primar val car1 = Mașină ("Peugeot 504", "XYZ234") // apeluri directe 1st sec. constructor val car2 = Mașină ("Peugeot 504", "XYZ234", false) // apeluri directe ultimul sec. constructor val car3 = Mașină ("Peugeot 504", "XYZ234", falsă, "gri") 

După cum am spus mai devreme, pentru a include în mod explicit un modificator de vizibilitate unui constructor dintr-o clasă, trebuie să includeți constructor cuvântul cheie - în mod implicit, constructorii sunt publici. 

constructor privat de mașină (numele val: String, val plateNo: String) // ... 

Aici, am făcut constructorul privat - aceasta înseamnă că utilizatorii nu pot instantiza un obiect folosind constructorul său direct. Acest lucru poate fi util dacă doriți ca utilizatorii să numească o altă metodă (o metodă din fabrică) pentru a face crearea obiectelor în mod indirect. 

2. Orice și nimic

În Kotlin, se numește tipul de vârf din ierarhia de tip Orice. Acest lucru este echivalent cu Java Obiect tip. Aceasta înseamnă că toate clasele din Kotlin au moștenire în mod explicit din Orice tip, inclusiv ŞirInt, Dubla, si asa mai departe. Orice tip conține trei metode: este egalătoString, și hashCode

Putem folosi de asemenea Nimic clasa în Kotlin în funcții care întotdeauna returnează o excepție - cu alte cuvinte, pentru funcții care nu se termină în mod normal. Când se întoarce o funcție Nimic, atunci știm că va face o excepție. În Java nu există un tip echivalent de acest tip. 

fun throwException (): Nimic arunca Excepție ("Mesaj de excepție")

Acest lucru poate fi util la testarea comportamentului de manipulare a erorilor în testele unității.   

3. Modificatori de vizibilitate

Modificatorii vizibilității ne ajută să restricționăm accesul publicului la API. Putem furniza diferiți modificatori de vizibilitate clasei, interfețele, obiectele, metodele sau proprietățile noastre. Kotlin ne oferă patru modificatori de vizibilitate:

Public

Acesta este setarea implicită și orice clasă, funcție, proprietate, interfață sau obiect care are acest modifier poate fi accesat de oriunde.

Privat 

O funcție de nivel superior, o interfață sau o clasă care este declarată ca privat pot fi accesate numai în cadrul aceluiași fișier. 

Orice funcție sau proprietate declarată privat în interiorul unei clase, a unui obiect sau a unei interfețe pot fi vizibile numai pentru alți membri ai aceleiași clase, obiecte sau interfețe. 

clasa Cont valoare privată val: Double = 0.0

Protejat

protejat Modificatorul poate fi aplicat numai proprietăților sau funcțiilor dintr-o clasă, obiect sau interfață - nu poate fi aplicat la funcții, clase sau interfețe de nivel superior. Proprietățile sau funcțiile cu acest modificator sunt accesibile numai în cadrul clasei care o definește și în orice subclasă. 

Intern 

Într - un proiect care are un modul (modulul Gradle sau Maven), o clasă, obiect, interfață sau funcție specificată cu intern modificatorul declarat în interiorul acelui modul este accesibil numai din cadrul acelui modul. 

clasa internă Contul val sum: Double = 0.0

4. Turnarea inteligentă

Turnarea înseamnă a lua un obiect de alt tip și a îl transforma într-un alt tip de obiect. De exemplu, în Java, folosim instanță de operator pentru a determina dacă un anumit tip de obiect este de alt tip înainte de a îl arunca.

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

După cum puteți vedea, am verificat dacă formă exemplu este Cerc, și apoi trebuie să aruncăm în mod explicit formă trimitere la a Cerc tip, astfel încât să putem apela metode de cerc tip. 

Un alt lucru minunat despre Kotlin este inteligența compilatorului său atunci când vine vorba de turnare. Să vedem acum o versiune în Kotlin.

/ * Kotlin * / dacă (forma este Cercul) shape.calCircumference (3.5)

Destul de curat! Compilatorul este inteligent să știe că dacă bloc va fi executat numai în cazul în care formă obiect este un exemplu de Cerc-astfel încât mecanismul de turnare se face sub capota pentru noi. Acum putem apela ușor proprietăți sau funcții ale Cerc tip în interiorul dacă bloc. 

if (forma este Circle && shape.hasRadius ()) println ("Radiusul cercului este shape.radius"

Aici, ultima condiție după && în dacă antetul va fi sunat numai când este prima condiție Adevărat. În cazul în care formă nu este o Cerc, ultima condiție nu va fi evaluată. 

5. Casting Explicit

Putem folosi la fel de operatorul (sau nesigure operator) pentru a arunca în mod explicit o referință de tip la alt tip în Kotlin. 

val cerc = formă ca Circle circle.calCircumference (4)

Dacă operația de turnare explicită este ilegală, rețineți că a ClassCastException va fi aruncat. Pentru a preveni ca o excepție să fie aruncată la turnare, putem folosi în condiții de siguranță operatorul (sau operatorul de casting nullable) la fel de?

val cerc: Cerc? = forma ca? Cerc

la fel de? operatorul va încerca să difuzeze la tipul dorit și se va întoarce nul dacă valoarea nu poate fi exprimată în loc să arunce o excepție. Amintiți-vă că un mecanism similar a fost discutat în secțiunea Nullabilitate în Nullabilitate, Loops și Condiții post în această serie. Citiți-vă acolo pentru o reîmprospătare.

6. Obiecte

Obiectele din Kotlin sunt mai asemănătoare obiectelor JavaScript decât obiectele Java. Rețineți că un obiect din Kotlin nu este o instanță a unei clase specifice!

Obiectele sunt foarte asemănătoare cu clasele. Iată câteva dintre caracteristicile obiectelor din Kotlin:

  • Ele pot avea proprietăți, metode și o init bloc.
  • Aceste proprietăți sau metode pot avea modificatori de vizibilitate.
  • Nu pot avea constructori (primari sau secundari).
  • Ele pot extinde alte clase sau pot implementa o interfață.

Acum să ne gândim cum să creăm un obiect.  

obiect Singleton fun myFunc (): Unitate // face ceva

Am plasat obiect înainte de numele obiectului pe care dorim să-l creăm. De fapt, noi creăm singletons atunci când creăm obiecte în Kotlin folosind obiect construi, deoarece există doar o instanță a unui obiect. Veți afla mai multe despre acest lucru atunci când discutăm despre interoperabilitatea obiectului cu Java. 

Un singur model este un model de design software care garantează că o clasă are doar o instanță și că un punct global de acces la acesta este furnizat de acea clasă. Ori de câte ori mai multe clase sau clienți solicită clasa, ei primesc aceeași instanță a clasei. Puteți verifica postul meu despre modelul singleton din Java pentru a afla mai multe despre el.

Puteți accesa obiectul sau singleton oriunde în proiect - atâta timp cât importați pachetul. 

Singleton.myFunc ()

Dacă sunteți un coder Java, acesta este modul în care creăm de obicei singleturi:

clasa publica Singleton private static Singleton INSTANCE = null; // alte variabile de instanță pot fi private private Singleton () ; public static sincronizat Singleton getInstance () if (INSTANCE == null) INSTANCE = new Singleton ();  retur (INSTANCE);  // pot fi urmate alte metode de instanță

După cum puteți vedea, folosind Kotlin obiect construi o face concisă și mai ușor de a crea singletons. 

Obiectele din Kotlin pot fi folosite și pentru a crea constante. În mod obișnuit, în Java, creăm constante într-o clasă făcându-i un câmp final static public, cum ar fi:

public final clasa APIConstants public static final String baseUrl = "http://www.myapi.com/"; private APIConstants () 

Acest cod în Java poate fi convertit în Kotlin mai succint, astfel:

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

Aici am declarat constanta APIConstants cu o proprietate baseUrl în interiorul unui pachet com.chike.kotlin.constants. Sub capota, un membru final Java static privat baseUrl este creat pentru noi și inițializat cu URL-ul șir. 

Pentru a folosi această constantă într-un alt pachet din Kotlin, pur și simplu importați pachetul.

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

Interoperabilitate Java

Kotlin convertește un obiect la o clasă Java finală sub capotă. Această clasă are un domeniu static privat INSTANȚĂ care deține o singură instanță (un singurton) din clasă. Următorul cod arată cum pur și simplu utilizatorii pot apela un obiect Kotlin din Java. 

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

Aici, o clasă Java a sunat Singleton a fost generat cu un membru final static public INSTANȚĂ, inclusiv o funcție publică finală myFunc ().

Pentru a face ca funcția sau proprietatea obiectului din Kotlin să fie un membru static al clasei Java generată, vom folosi @JvmStatic adnotare. Iată cum să îl folosiți:

Obiect Singleton @JvmStatic distracție myFunc (): Unitate // face ceva

Aplicând @JvmStatic adnotare la myFunc (), compilatorul la transformat într-o funcție statică. 

Acum, apelanții Java pot să-l numească ca un apel membru static normal. Rețineți că utilizarea funcției INSTANȚĂ câmpul static pentru a apela membrii va funcționa în continuare.

/ * Java * / Singleton.myFunc ()

7. Obiectele Companion

Acum am ajuns să înțelegem ce obiecte sunt în Kotlin, să ne aruncăm într-un alt fel de obiecte numite obiecte însoțitoare. 

Deoarece Kotlin nu susține clase statice, metode sau proprietăți precum cele pe care le avem în Java, echipa Kotlin ne-a oferit o alternativă mai puternică numită obiecte de însoțitoare. Un obiect însoțitor este în esență un obiect care aparține unei clase - această clasă este cunoscută ca clasă de însoțitoare a obiectului. Acest lucru înseamnă, de asemenea, că caracteristicile pe care le-am menționat pentru obiecte se aplică și obiectelor însoțitoare. 

Crearea unui obiect Companion

Similar cu metodele statice din Java, un obiect însoțitor nu este asociat cu o instanță de clasă, ci mai degrabă cu clasa însăși - de exemplu, o metodă statică din fabrică, care are sarcina de a crea o instanță de clasă. 

(Nume: String, LastName: String) person-in-person (FirstName, lastName)

Aici, am făcut constructorul privat-acest lucru înseamnă că utilizatorii din afara clasei nu pot crea direct o instanță. În interiorul blocului nostru de obiecte, avem o funcție crea(), care creează o Persoană obiect și îl întoarce. 

Invocarea unei funcții Object Companion

companion instanțierea obiectelor este leneș. Cu alte cuvinte, aceasta va fi instanțiată numai atunci când este necesar prima dată. Instanția unui a companion obiect se întâmplă atunci când o instanță a companion clasa este creată sau companion membrii obiectului sunt accesați. 

Să vedem cum să invocăm o funcție de obiect însoțitor în Kotlin.

val person = Personal.create ("Cersei", "Lannister") println (person.firstName) // imprimă "Cersei"

După cum puteți vedea, aceasta este la fel ca invocarea unei metode statice în Java ca în mod normal. Cu alte cuvinte, pur și simplu sunăm la clasă și apoi sunăm membrul. Rețineți că, în afară de funcții, putem avea și proprietăți în interiorul obiectului de companie. 

(nume_firma: String, lastName: String) person_name (firstName, lastName) init println ("Creat obiect persoană personalizată")

Rețineți, de asemenea, că companion clasa are acces nelimitat la toate proprietățile și funcțiile declarate în obiectul însoțitor, în timp ce un obiect însoțitor nu poate accesa membrii clasei. Putem avea un init bloc de cod în interiorul a companion obiect - aceasta se numește imediat când este creat obiectul însoțitor. 

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

Rezultatul executării codului de mai sus va fi: 

Persoana însoțitoare persoană creată 2

Amintiți-vă, doar o singură instanță a unei clase companion obiect poate exista vreodată. 

De asemenea, suntem liberi să oferim un obiect de însoțire cu un nume. 

// ... obiect de companie Companion var count: int = 0 fun create (firstName: String, lastName: String): Persoana = Persoana (FirstName, lastName) // ... 

Aici i-am dat un nume numit Fabrică. Atunci putem spune așa în Kotlin:

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

Acest stil este verbose, astfel încât să rămânem mult mai favorabil. Dar acest lucru ar putea fi util atunci când apelați o funcție de obiect însoțitor sau o proprietate din Java.

Așa cum am spus mai devreme, ca obiecte, obiectele însoțitoare pot include și proprietăți sau funcții, implementează interfețe și chiar extind o clasă. 

interfață PersonFactory fun create (nume_firmo: String, lastName: String): Persoană clasă Constructor privat person (var firstName: String, var lastName: String) object companion: PersonFactory  : Persoana returnează persoana (numeName, NumeNu)

Aici avem o interfață PersonFactory cu doar un singur crea() funcţie. Privind la noile noastre modificate companion obiect, aceasta implementează acum această interfață (veți afla despre interfețe și moștenire în Kotlin într-un post mai târziu). 

Interoperabilitate Java

Sub capota, obiectele însoțitoare sunt compilate în mod similar cu modul în care este compilat un obiect Kotlin. În cazul nostru, două clase sunt generate pentru noi: o finală Persoană clasă și o clasă finală statică internă Persoana $ Companion

Persoană clasa conține un membru static final numit companion-acest câmp static este un obiect al Persoana $ Companion clasa interioară. Persoana $ Companion clasa interioară are și membrii proprii, iar una dintre ele este o funcție publică finală numită crea()

Rețineți că nu am dat un nume de obiect însoțitor, deci clasa internă statică generată a fost companion. Dacă i-ar fi dat un nume, atunci numele generat ar fi numele pe care l-am dat în Kotlin. 

/ * Java * / Persoană persoană = Person.Companion.create ("Jon", "Snow"); 

Aici, obiectul însoțitor din Kotlin nu are nume, așa că folosim numele companion furnizate de compilatorul pentru apelanții Java pentru a-l apela.

@JvmStatic adnotarea aplicată pe un membru al unui obiect însoțitor funcționează similar cu modul în care funcționează pentru un obiect obișnuit. 

Companion Object Extensions

Similar cu modul în care funcțiile extensiei pot extinde funcționalitatea unei clase, putem extinde funcționalitatea unui obiect însoțitor. (Dacă doriți o reîmprospătare a funcțiilor de extensie în Kotlin, vizitați tutorialul Advanced Functions din această serie). 

classA comanda obiect  distracție ClassA.Companion.extFunc () // ... face implementarea ClassA.extFunc ()

Aici, am definit o funcție de extensie extFunc () pe obiectul însoțitor ClassA.Companion. Cu alte cuvinte, extfunc () este o extensie a obiectului de companie. Apoi putem apela extensia ca și cum ar fi o funcție membră (nu este!) A obiectului însoțitor. 

În spatele scenei, compilatorul va crea o funcție utilitară statică extFunc (). Obiectul receptorului ca argument pentru această funcție de utilitate este ClassA $ Companion

Concluzie

În acest tutorial, ați învățat despre clasele de bază și obiectele de la Kotlin. Am abordat următoarele aspecte despre clase:

  • creație de clasă
  • constructori
  • proprietăţi
  • vizibilitate modificatori
  • inteligent de turnare
  • casting explicit 

De asemenea, ați aflat despre modul în care obiectele și obiectele însoțitoare din Kotlin pot înlocui cu ușurință metodele statice, constantele și singleton-urile pe care le codificați în Java. Dar asta nu este tot! Mai sunt multe de învățat despre cursurile de la Kotlin. În următorul post, vă voi arăta caracteristici mai interesante pe care Kotlin le are pentru programarea orientată pe obiecte. Ne vedem în curând!

Pentru a afla mai multe despre limba Kotlin, vă recomand să vizitați documentația Kotlin. Sau verificați câteva dintre celelalte postări pentru dezvoltarea aplicațiilor Android aici pe Envato Tuts+!

Cod