Kotlin fra grunnen Klasser og objekter

Kotlin er et moderne programmeringsspråk som kompilerer til Java bytecode. Det er gratis og åpen kildekode, og lover å gjøre koding for Android enda morsommere.  

I forrige artikkel lærte du avansert bruk av funksjoner, for eksempel utvidelsesfunksjoner, nedleggelser, høyere rekkefølgefunksjoner og inline-funksjoner i Kotlin. 

I dette innlegget får du en introduksjon til objektorientert programmering i Kotlin ved å lære om klasser: konstruktører og egenskaper, avstøpning og mer avanserte klassen funksjoner som Kotlin gjør lett. 

1. Klasser

En klasse er en programgruppe som sammenstiller funksjoner og data for å utføre noen relaterte oppgaver. Vi erklærer en klasse i Kotlin ved hjelp av klasse søkeord som ligner på Java. 

klassebok

Den forrige koden er den enkleste klassedeklarasjonen. Vi har nettopp opprettet en tom klasse som heter Bok.  Vi kan fortsatt instantiere denne klassen selv om den ikke inneholder en kropp som bruker standardkonstruktøren.

val bok = bok ()

Som du kan observere i koden ovenfor, brukte vi ikke ny søkeord for å ordne denne klassen - som det er vanlig i andre programmeringsspråk. ny er ikke et søkeord i Kotlin. Dette gjør vår kildekode konsistent når du oppretter en klasseeksempel. Men vær oppmerksom på at instantiering av en Kotlin-klasse i Java vil kreve ny søkeord. 

// I en Java-fil Bokbok = Ny bok ()

Klassekonstruksjoner og egenskaper

La oss se på hvordan du legger til en konstruktør og egenskaper i vår klasse. Men først, la oss se en typisk klasse i Java:

/ * Java * / offentlig klasse Book private String title; privat Long isbn; Offentlig bok (Stringtittel, Long isbn) this.title = title; this.isbn = isbn;  offentlig String getTitle () retur tittel;  Offentlig tomgang setTitle (Stringtittel) this.title = title;  offentlig Long getIsbn () return isbn;  offentlig tomgang setIsbn (Long isbn) this.isbn = isbn; 

Ser på vår Bok modell klasse over, har vi følgende:

  • to felt: tittel og isbn
  • en enkelt konstruktør
  • getters og setters for de to feltene (heldigvis kan IntelliJ IDEA hjelpe oss med å generere disse metodene)

La oss nå se på hvordan vi kan skrive den forrige koden i Kotlin i stedet:

/ * Kotlin * / klassebok varittel: String var isbn: Long constructor (tittel: String, isbn: Long) this.title = title this.isbn = isbn

En ganske ryddig klasse! Vi har nå redusert antall linjer med kode fra 20 til bare 9. Den konstruktør () funksjon kalles a sekundær konstruktør i Kotlin. Denne konstruktøren er ekvivalent med Java-konstruktøren som vi ringte da instantiating en klasse. 

I Kotlin er det ikke noe begrep om et felt som du kanskje er kjent med; I stedet bruker det begrepet "egenskaper". For eksempel har vi to mutable (read-write) egenskaper deklarert med Var søkeord: tittel og isbn i Bok klasse. (Hvis du trenger en oppdatering på variabler i Kotlin, vennligst besøk det første innlegget i denne serien: Variabler, Grunntyper og Arrays). 

En fantastisk ting er at getters og setters for disse egenskapene er automatisk generert for oss under hetten av Kotlin-kompilatoren. Legg merke til at vi ikke angav noen siktmodifikatorer til disse egenskapene-så som standard er de offentlige. Med andre ord kan de nås fra hvor som helst.

La oss se på en annen versjon av samme klasse i Kotlin:

klasse Bokkonstruktør (tittel: String, isbn: Lang) varittel: String var isbn: Long init this.title = title this.isbn = isbn

I denne koden har vi fjernet den sekundære konstruktøren. I stedet forklarte vi en konstruktør i klassen header kalt a primærkonstruktør. En primærkonstruktør har ikke noe sted å sette en blokk med kode, så vi bruker i det modifikator for å initialisere innkommende parametere fra den primære konstruktøren. Legg merke til at i det kodeblokk utføres umiddelbart når klasseeksemplet er opprettet.

Som du ser, har koden vår fortsatt mye kjele. La oss redusere det videre:

klasse bok konstruktør (var tittel: streng, var isbn: lang)

Våre Bok klassen er nå bare en linje med kode. Det er veldig kult! Legg merke til at i den primære konstruktørparameterlisten, definerte vi våre mutable egenskaper: tittel og isbn direkte innenfor den primære konstruktøren med Var søkeord. 

Vi kan også legge til standardverdier til noen av klassegenskapene rett innenfor konstruktøren.

klassebokkonstruktør (varittel: String = "standardverdien", var isbn: Lang)

Faktisk kan vi også utelate konstruktør søkeord, men bare hvis det ikke har noen sikt modifikator (offentlig, privat, eller beskyttet) eller noen merknader. 

klasse bok (var tittel: String = "standard verdi", var isbn: lang)

En veldig fin klasse, jeg må si!

Vi kan nå opprette en klasseeksempel som denne:

val book = Book ("En sang av is og brann", 9780007477159) val book2 = Book (1234) // bruker tittelegenskapens standardverdi

Tilgang til og innstilling av egenskaper 

I Kotlin kan vi få en eiendom av klasseobjektet bok, etterfulgt av en punktseparator ., deretter eiendommens navn tittel. Denne konsise stilen med tilgang til egenskaper kalles syntax for eiendomstilgang. Med andre ord, vi trenger ikke å ringe egenskapen getter-metoden for å få tilgang til eller ringe setteren for å sette en eiendom i Kotlin-som vi gjør i Java. 

println (book.title) // "En sang av is og brann"

Fordi det isbn Eiendommen er erklært med Var søkeord (read-write), kan vi også endre eiendomsverdien ved hjelp av oppdragsoperatøren =.

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

La oss se et annet eksempel:

klassebok (varittel: String, val isbn: Lang) valbok = Bok ("En sang av is og brann", 9780007477159) book.isbn = 1234 // feil: skrivebeskyttet eiendom book.title = "Ting faller fra hverandre "// omfordelt tittel med verdi

Her oppdaterte vi isbn parameter for å være uforanderlig (skrivebeskyttet) i stedet - ved å bruke val søkeord. Vi instanserte en klasseeksempel bok og reassigned tittel eiendom verdien "Ting faller Apart". Legg merke til at når vi prøvde å omfordele isbn eiendomsverdi til 1234, kompilatoren klaget. Dette skyldes at eiendommen er uendelig, etter å ha blitt definert med val søkeord. 

Java interoperabilitet

Vær oppmerksom på at ved å erklære en parameter med Var modifikator i den primære konstruktøren, har Kotlin-kompilatoren (bak kulissene) hjulpet oss med å generere både eiendomsaksessene: getter og setter. Hvis du bruker val, det vil generere bare getteren. 

/ * Kotlin * / klasse Bok (var tittel: String, val isbn: Long)

Dette betyr at Java-oppringere bare kan få eller angi eiendomsfeltet ved å ringe til setter- eller getter-metoden for eiendommen. Husk at dette avhenger av modifikatoren som brukes til å definere Kotlin-egenskapen: Var eller val

/ * Java * / Bokbok = Ny bok ("En sang av is og brann", 9780385474542) println (book.getTitle ()) // "En sang av is og brann" book.setTitle ("Things Fall Apart") // setter ny verdi println (book.getTitle ()) // "Things fall Apart" book.getIsbn () // 9780385474542 book.setIsbn (4545454) // vil ikke kompilere

Custom Getters og Setters

I denne delen vil jeg vise deg hvordan du oppretter egendefinerte accessorer (getters og setters) for en eiendom i Kotlin hvis du vil. Å lage en tilpasset setter kan være nyttig hvis du vil validere eller verifisere en verdi før den er satt til en klasseegenskap. Og en tilpasset eiendom getter kan være nyttig når du vil endre eller endre verdien som skal returneres.  

Opprette en tilpasset setter

Fordi vi ønsker å lage vår egen tilpassede getter eller setter for en eiendom, må vi definere den egenskapen i klassekroppen i stedet for konstruktørens topptekst. 

klasse bok (val isbn: lang) var title = "standard verdi"

Dette er grunnen til at vi flyttet den mutable (read-write) tittel eiendom inn i klassekroppen og ga den en standardverdi (eller det ville ikke kompilere).  

klassen bok (val isbn: lang) var title = "default value" sett (verdi) hvis (! value.isNotEmpty ()) kaste IllegalArgumentException ("Tittel må ikke være tom") field = value

Du kan se vi definerte vår egen setter metode sett (verdi) for tittel rett under eiendomsdefinisjonen som du ikke kan endre dette sett() metode signatur fordi dette er hva kompilatoren forventer som en egendefinert egenskap setter funksjon.

Parameteren verdi passert til sett Metoden representerer den faktiske verdien som ble tildelt eiendommen av brukere. Du kan endre parameternavnet hvis du ønsker det, men verdi er mye foretrukket. Vi validerte verdi ved å sjekke om verdien er tom. Hvis tom, slutte å utføre og kaste unntak; Ellers må du tilordne verdien til en spesiell felt variabel.

Denne spesielle felt variabelt felt inne i sett Metoden er et alias for bakkefeltet til eiendommen. Et bakfelt er bare et felt som brukes av egenskaper når du vil endre eller bruke feltdataene. I motsetning til verdi, Du kan ikke gi nytt navn til denne spesielle felt variabel.

Opprette en tilpasset getter

Det er veldig enkelt å lage en tilpasset getter for en eiendom i Kotlin. 

klassen bok (val isbn: lang) var title = "standard verdi" // ... sett metode få () return field.toUpperCase ()

Inne i Metode, vi returnerer bare en endret felt-i vårt tilfelle, vi returnerte boken tittelen i store bokstaver. 

val book = Book (9780007477159) book.title = "En sang av is og brann" println (book.title) // "ET SONG OF ICE AND FIRE" println (book.isbn) // 9780007477159

Legg merke til at hver gang vi setter en verdi til tittel eiendom, dens sett Metoden blokk utføres - det samme gjelder for  metode hver gang vi henter den. 

Hvis du vil lære om medlemsfunksjoner for en Kotlin-klasse (hvilken type funksjon som er definert i en klasse, et objekt eller et grensesnitt), kan du besøke posten Mer moro med funksjoner i denne serien. 

Mer om byggere

Som jeg diskuterte tidligere, har vi to typer konstruktører i Kotlin: primær og sekundær. Vi har friheten til å kombinere begge i en enkelt klasse, som du kan se i eksemplet nedenfor:

Klasse Bil (val navn: String, val plateNo: String) var nytt: Boolsk = ekte konstruktør (navn: String, plateNo: String, ny: Boolsk): dette (navn, plateNo) this.new = new

Vær oppmerksom på at vi ikke kan erklære eiendommer i en sekundær konstruktør, som vi gjorde for den primære konstruktøren. Hvis vi vil gjøre dette, må vi deklarere det inne i klassekroppen og deretter initialisere det i den sekundære konstruktøren.  

I koden ovenfor angir vi standardverdien til ny eiendom for klassen Bil (huske, ny er ikke et søkeord i Kotlin) -Vi kan da bruke den sekundære konstruktøren til å endre den hvis vi vil. I Kotlin må hver sekundær konstruktør ringe til den primære konstruktøren, eller ring en annen sekundær konstruktør som kaller den primære konstruktøren-vi bruker dette søkeord for å oppnå det. 

Legg merke til at vi kan ha flere sekundære konstruktører inne i en klasse. 

Klasse Bil (val navn: String, val plateNo: String) var new: Boolean? = null var farge: String = "" konstruktør (navn: String, plateNo: String, ny: Boolean): dette (navn, plateNo) this.new = new constructor (navn: String, plateNo: String, ny: Boolean , farge: String): dette (navn, plateNo, nytt) this.colour = color

Hvis en klasse utvider en superklasse, så kan vi bruke super søkeord (ligner på Java) for å ringe superklassekonstruktøren (vi diskuterer arv i Kotlin i et fremtidig innlegg). 

// direkte kalles primærkonstruktor val car1 = Bil ("Peugeot 504", "XYZ234") // direkte samtaler 1. sek. constructor val car2 = Bil ("Peugeot 504", "XYZ234", falsk) // direkte samtaler siste sekund. constructor val car3 = Bil ("Peugeot 504", "XYZ234", falsk, "grå") 

Som jeg sa tidligere, for at vi eksplisitt skal ta med en siktmodifikator til en konstruktør i en klasse, må vi inkludere konstruktør Søkeord - Som standard er konstruktører offentlige. 

klassen Car private constructor (val navn: String, val plateNo: String) // ... 

Her laget vi konstruktøren privat - det betyr at brukerne ikke kan instantiere et objekt direkte ved hjelp av konstruktøren. Dette kan være nyttig hvis du vil at brukerne i stedet skal ringe en annen metode (en fabrikkmetode) for å gjøre opprettelsen av objekter indirekte. 

2. Enhver og ingenting typer

I Kotlin kalles den øverste typen i typen hierarki Noen. Dette tilsvarer Java Gjenstand type. Dette betyr at alle klasser i Kotlin eksplisitt arver fra Noen skriv inn, inkludert stringint, Dobbelt, og så videre. De Noen typen inneholder tre metoder: er liktoString, og hashCode

Vi kan også benytte Ingenting klasse i Kotlin i funksjoner som alltid returnerer et unntak, med andre ord, for funksjoner som ikke avslutter normalt. Når en funksjon returnerer Ingenting, da vet vi at det kommer til å kaste et unntak. Ingen tilsvarende type av denne typen finnes i Java. 

morsomt kaste Eksempel (): Ingenting kaste Unntak ("Unntaksmelding")

Dette kan komme til nytte når du tester feilhåndteringsadferd i enhetstester.   

3. Siktmodifikatorer

Siktmodifikatorer hjelper oss å begrense tilgjengeligheten av API-en vår til publikum. Vi kan gi forskjellige synlighetsmodifikatorer til våre klasser, grensesnitt, objekter, metoder eller egenskaper. Kotlin gir oss fire sikringsmodifikatorer:

Offentlig

Dette er standard, og hvilken som helst klasse, funksjon, egenskap, grensesnitt eller objekt som har denne modifikatoren kan nås hvor som helst.

Privat 

En toppnivåfunksjon, grensesnitt eller klasse som er erklært som privat kan bare nås i samme fil. 

Eventuell funksjon eller eiendom som er erklært privat inne i en klasse, objekt eller grensesnitt kan bare være synlig for andre medlemmer av samme klasse, objekt eller grensesnitt. 

klassekonto privat val beløp: dobbelt = 0,0

beskyttet

De beskyttet Modifier kan kun brukes på egenskaper eller funksjoner i en klasse, objekt eller grensesnitt. Det kan ikke brukes på toppnivå funksjoner, klasser eller grensesnitt. Egenskaper eller funksjoner med denne modifikatoren er bare tilgjengelige i klassen som definerer den og noen underklasse. 

Innvendig 

I et prosjekt som har en modul (Gradle eller Maven modul), en klasse, objekt, grensesnitt eller funksjon spesifisert med innvendig Modifikator som er oppgitt i den modulen, er bare tilgjengelig fra den modulen. 

intern klasse Konto valbeløp: Dobbel = 0.0

4. Smart Casting

Casting betyr å ta et objekt av en annen type og konvertere den til en annen objekttype. For eksempel, i Java, bruker vi tilfelle av operatør for å avgjøre om en bestemt objekttype er av en annen type før vi deretter støtter den.

/ * Java * / if (form instanceof Circle) Sirkelsirkel = (Circle) form; circle.calCircumference (3,5); 

Som du kan se, sjekket vi om form forekomsten er Sirkel, og da må vi eksplisitt kaste form referanse til a Sirkel skriv slik at vi kan ringe metoder for sirkel type. 

En annen fantastisk ting om Kotlin er smartheten til kompilatoren når det kommer til støping. La oss nå se en versjon i Kotlin.

/ * Kotlin * / hvis (form er sirkel) shape.calCircumference (3.5)

Temmelig stilig! Kompilatoren er smart å vite at hvis blokkering vil bli utført bare hvis form objekt er en forekomst av Sirkel-så støpemekanismen er gjort under hetten for oss. Vi kan nå enkelt ringe egenskaper eller funksjoner av Sirkel skriv inn i hvis blokkere. 

hvis (form er sirkel && shape.hasRadius ()) println ("Sirkelradien er shape.radius")

Her er den siste tilstanden etter && i hvis header blir bare kalt når den første tilstanden er ekte. Hvis form er ikke en Sirkel, da vil den siste tilstanden ikke bli vurdert. 

5. Eksplisitt støping

Vi kan bruke som operatør (eller usikre cast operatør) for å eksplisitt kaste en referanse av en type til en annen type i Kotlin. 

valcirkel = form som sirkelkrets.calomkrets (4)

Hvis den eksplisitte avstøpningsoperasjonen er ulovlig, merk at a ClassCastException vil bli kastet. For å forhindre at et unntak kastes når du støper, kan vi bruke trygt kastet operatør (eller nulloperert operatør) som?

val sirkel: sirkel? = form som? Sirkel

De som? Operatøren vil forsøke å kaste til ønsket type, og den kommer tilbake null hvis verdien ikke kan kastes i stedet for å kaste unntak. Husk at en lignende mekanisme ble diskutert i Nullability-delen i Nullability, Loops og Conditions post i denne serien. Les opp der for en oppfriskning.

6. objekter

Objekter i Kotlin ligner mer JavaScript-objekter enn Java-objekter. Merk at et objekt i Kotlin ikke er en forekomst av en bestemt klasse!

Objekter er veldig lik klasser. Her er noen av egenskapene til objekter i Kotlin:

  • De kan ha egenskaper, metoder og an i det blokkere.
  • Disse egenskapene eller metodene kan ha synlighetsmodifikatorer.
  • De kan ikke ha konstruktører (primær eller sekundær).
  • De kan utvide andre klasser eller implementere et grensesnitt.

La oss nå grave på hvordan du lager et objekt.  

objekt Singleton morsom myFunc (): Enhet // gjør noe

Vi plasserer gjenstand søkeord før navnet på objektet vi vil opprette. Faktisk lager vi singler når vi lager objekter i Kotlin ved hjelp av gjenstand konstruere, fordi bare en forekomst av et objekt eksisterer. Du lærer mer om dette når vi diskuterer objektinteroperabilitet med Java. 

En singleton er et programvareutformningsmønster som garanterer at en klasse bare har én forekomst, og et globalt punkt for tilgang til det er gitt av den klassen. Hver gang flere klasser eller klienter ber om klassen, får de samme forekomst av klassen. Du kan sjekke ut innlegget mitt om singleton-mønsteret i Java for å lære mer om det.

Du kan få tilgang til objektet eller singleton hvor som helst i prosjektet ditt, så lenge du importerer pakken. 

Singleton.myFunc ()

Hvis du er en Java-koder, oppretter du vanligvis singletoner:

offentlig klasse Singleton privat statisk Singleton INSTANCE = null; // andre forekomstvariabler kan være her private Singleton () ; offentlig statisk synkronisert Singleton getInstance () if (INSTANCE == null) INSTANCE = new Singleton ();  retur (INSTANCE);  // andre forekomstmetoder kan følge

Som du kan se, bruker du Kotlin gjenstand konstruksjon gjør det konsistent og lettere å lage singletoner. 

Objekter i Kotlin kan også benyttes for å skape konstanter. Vanligvis i Java lager vi konstanter i en klasse ved å gjøre det til et offentlig statisk sluttfelt som dette:

offentlig endelige klasse APIConstanter offentlig statisk endelig String baseUrl = "http://www.myapi.com/"; private APIConstanter () 

Denne koden i Java kan konverteres til Kotlin mer kortfattet slik:

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

Her erklærte vi konstanten APIConstants med en eiendom baseURL inne i en pakke com.chike.kotlin.constants. Under hetten, et Java privat statisk sluttmedlem baseURL er opprettet for oss og initialisert med strengen nettadressen. 

For å bruke denne konstanten i en annen pakke i Kotlin, bare importere pakken.

importer com.chike.kotlin.constants.APIConstants APIConstants.baseUrl

Java interoperabilitet

Kotlin konverterer en gjenstand til en endelig Java-klasse under hetten. Denne klassen har et privat statisk felt FOREKOMST som har en enkelt forekomst (en singleton) av klassen. Følgende kode viser hvordan enkelt brukere kan ringe et Kotlin-objekt fra Java. 

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

Her heter en Java-klasse Singleton ble generert med et offentlig statisk sluttmedlem FOREKOMST, inkludert en offentlig sluttfunksjon myfunc ().

For å gjøre objektfunksjonen eller egenskapen i Kotlin et statisk medlem av den genererte Java-klassen, bruker vi @JvmStatic merknad. Slik bruker du det:

objekt Singleton @JvmStatic fun myFunc (): Enhet // gjør noe

Ved å bruke @JvmStatic annotasjon til myfunc (), kompilatoren har gjort det til en statisk funksjon. 

Nå kan Java-oppringere kalle det som en vanlig statisk medlemskall. Legg merke til at du bruker FOREKOMST Statisk felt for å ringe medlemmer vil fortsatt fungere.

/ * Java * / Singleton.myFunc ()

7. Companion Objects

Nå har vi forstått hva objekter er i Kotlin, la oss dykke inn i en annen type gjenstander kalt følgesvennobjekter. 

Fordi Kotlin ikke støtter statiske klasser, metoder eller egenskaper som de vi har i Java, ga Kotlin-teamet oss et kraftigere alternativ som heter følgesvenn objekter. Et følgesvennobjekt er i utgangspunktet en gjenstand som tilhører en klasse - denne klassen er kjent som objektets følgesvenn. Dette betyr også at egenskapene jeg nevnte for objekter, også gjelder for følgesvenner. 

Opprette et følgesvennobjekt

I likhet med statiske metoder i Java, er et følgesvenn ikke tilknyttet en klasseeksempler, men heller med klassen selv, for eksempel en fabrikkstatisk metode som har jobben med å lage en klasseeksempel. 

klasse Person privat konstruktør (var førstnavn: String, var etternavn: String) følgesvennobjekt morsomt opprett (fornavn: String, etternavn: String): Person = Person (fornavn, etternavn)

Her laget vi konstruktøren privat-Dette betyr at brukere utenfor klassen ikke kan opprette en forekomst direkte. Inne i kompanjonsobjektet har vi en funksjon skape(), som skaper en Person objekt og returnerer den. 

Invokere en Companion Object-funksjon

kompanjong objekt instantiation er lat. Med andre ord, vil det bli instantiated bare når det trengs for første gang. Etablering av a kompanjong objekt skjer når en forekomst av kompanjong klassen er opprettet eller kompanjong objekt medlemmer er tilgjengelig. 

La oss se hvordan å påkalle en følgesvennfunksjon i Kotlin.

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

Som du kan se, er dette akkurat som å påberope seg en statisk metode i Java som vanlig. Med andre ord, vi ringer bare på klassen og kaller medlemmet. Merk at bortsett fra funksjoner, kan vi også ha egenskaper innenfor vårt følgesvennobjekt. 

Klasse Person privat konstruktør (var førstnavn: String, var lastnavn: String) init count ++ companion objekt var telle: Int = 0 moro opprette (firstName: String, LastName: String): Person = Person (firstName, lastName) init println ("Person companion object created")

Legg også merke til at kompanjong klassen har ubegrenset tilgang til alle egenskapene og funksjonene deklarert i følgesvennobjektet, mens et følgesvennobjekt ikke kan få tilgang til klassemedlemmene. Vi kan ha en i det kode blokk inne a kompanjong objekt - dette kalles umiddelbart når følgesvennobjektet opprettes. 

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

Resultatet av å utføre koden ovenfor vil være: 

Personkammeratobjekt opprettet 2

Husk, bare en enkelt forekomst av en klasse kompanjong objekt kan noen gang eksistere. 

Vi er også gratis å gi vårt følgesvennobjekt med et navn. 

// ... companion object Fabrikk var telle: Int = 0 moro opprette (firstName: String, LastName: String): Person = Person (fornavn, etternavn) // ... 

Her ga vi det et navn som heter Fabrikk. Vi kan da kalle det slik i Kotlin:

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

Denne stilen er verbose, så det er mye å foretrekke med å klatre med den forrige måten. Men dette kan komme til nytte når du ringer en ledsagerobjektfunksjon eller en eiendom fra Java.

Som jeg sa tidligere, kan gjenstander som objekter også inneholde egenskaper eller funksjoner, implementere grensesnitt, og til og med utvide en klasse. 

grensesnitt PersonFactory morsom opprettelse (firstName: String, lastName: String): Person class Person privatkonstruktør (var førstnavn: String, var lastnavn: String) følgesvennobjekt: PersonFactory overstyr sjarmopprettelse (firstName: String, LastName: String) : Person retur Person (fornavn, etternavn)

Her har vi et grensesnitt PersonFactory med bare en singel skape() funksjon. Ser på vår nye modifisert kompanjong objekt, det implementerer nå dette grensesnittet (du vil lære om grensesnitt og arv i Kotlin i et senere innlegg). 

Java interoperabilitet

Under hetten blir kompanjonsobjekter utarbeidet på samme måte som et Kotlin-objekt er kompilert. I vårt eget tilfelle genereres to klasser for oss: en endelig Person klasse og en indre statisk siste klasse Person $ Companion

De Person Klassen inneholder et siste statisk medlem som heter Kompanjong-dette statiske feltet er et objekt av Person $ Companion indre klasse. De Person $ Companion indre klasse har også egne medlemmer, og en av dem er en offentlig endelig funksjon kalt skape()

Vær oppmerksom på at vi ikke ga vårt følgesvenn et navn, så den genererte statiske indre klassen var Kompanjong. Hvis vi hadde gitt det et navn, ville det genererte navnet være navnet vi ga det i Kotlin. 

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

Her har følgesvennobjektet i Kotlin ikke noe navn, så vi bruker navnet Kompanjong levert av kompilatoren for Java-oppringere for å ringe det.

De @JvmStatic annotering som brukes på et følgesvennobjektmedlem, fungerer på samme måte som det virker for en vanlig gjenstand. 

Companion Object Extensions

På samme måte som utvidelsesfunksjoner kan forlenge funksjonaliteten til en klasse, kan vi også forlenge funksjonaliteten til et følgesvennobjekt. (Hvis du vil ha en oppdatering på utvidelsesfunksjoner i Kotlin, kan du gå til veiledningen for avanserte funksjoner i denne serien). 

klasse ClassA companion object  morsom ClassA.Companion.extFunc () // ... gjør implementering ClassA.extFunc ()

Her definerte vi en utvidelsesfunksjon extFunc () på følgesvennobjektet ClassA.Companion. Med andre ord, extfunc () er en forlengelse av følgesvennobjektet. Da kan vi ringe utvidelsen som om det er en medlemsfunksjon (det er ikke!) Av følgesvennobjektet. 

Bak kulissene, vil kompilatoren opprette en statisk verktøyfunksjon extFunc (). Mottakerobjektet som et argument til denne funksjonen er Classa $ Companion

Konklusjon

I denne opplæringen lærte du om grunnleggende klasser og objekter i Kotlin. Vi dekket følgende om klasser:

  • klasseopprettelse
  • konstruktører
  • eiendommer
  • synlighetsmodifikatorer
  • smart støping
  • eksplisitt avstøpning 

Du lærte også om hvordan objekter og kompanjonsobjekter i Kotlin enkelt kan erstatte statiske metoder, konstanter og singletoner du kodes i Java. Men det er ikke alt! Det er fortsatt mer å lære om klasser i Kotlin. I neste innlegg vil jeg vise deg enda flere kule funksjoner som Kotlin har for objektorientert programmering. Ser deg snart!

For å lære mer om Kotlin-språket, anbefaler jeg at du besøker Kotlin-dokumentasjonen. Eller sjekk ut noen av våre andre Android-apputviklingsposter her på Envato Tuts+!