Kotlin is een moderne programmeertaal die compileert met Java bytecode. Het is gratis en open source en belooft om het coderen voor Android nog leuker te maken.
In het vorige artikel leerde je geavanceerd gebruik van functies, zoals uitbreidingsfuncties, sluitingen, hogere orde functies en inline functies in Kotlin.
In dit bericht krijg je een inleiding tot object-georiënteerd programmeren in Kotlin door te leren over klassen: constructors en eigenschappen, casting en meer geavanceerde klassefuncties die Kotlin gemakkelijk maakt.
Een klasse is een programma-eenheid die functies en gegevens samenvoegt om een aantal gerelateerde taken uit te voeren. We verklaren een klas in Kotlin met behulp van de klasse
trefwoord - vergelijkbaar met Java.
klasboek
De voorgaande code is de eenvoudigste klassenverklaring: we hebben zojuist een lege klasse gemaakt met de naam Boek
. We kunnen deze klasse nog steeds een instantie geven, zelfs als deze geen instantie bevat die de standaardconstructor gebruikt.
val boek = Boek ()
Zoals je kunt zien in de bovenstaande code, hebben we de nieuwe
sleutelwoord om deze klasse te instantiëren, zoals gebruikelijk is in andere programmeertalen. nieuwe
is geen trefwoord in Kotlin. Dit maakt onze broncode bondig bij het maken van een klasse-instantie. Maar houd er rekening mee dat voor het instantiëren van een Kotlin-klasse in Java de nieuwe
trefwoord.
// In een Java-bestand Boekboek = nieuw boek ()
Laten we eens kijken hoe we een constructor en eigenschappen aan onze klas kunnen toevoegen. Maar laten we eerst een typische klasse in Java bekijken:
/ * Java * / public class Book private String title; privé Long isbn; public Book (String title, Long isbn) this.title = title; this.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;
Kijkend naar onze Boek
modelklasse hierboven, we hebben het volgende:
titel
en isbn
Laten we nu kijken naar hoe we de vorige code in Kotlin kunnen schrijven in plaats van:
/ * Kotlin * / class Book var title: String var isbn: Long constructor (title: String, isbn: Long) this.title = title this.isbn = isbn
Een mooie nette klas! We hebben nu het aantal coderegels teruggebracht van 20 naar slechts 9. Het constructor ()
functie wordt a genoemd secundaire constructor in Kotlin. Deze constructor is equivalent aan de Java-constructor die we hebben gebruikt bij het instantiëren van een klasse.
In Kotlin is er geen concept van een veld zoals je misschien kent; in plaats daarvan gebruikt het het concept van "eigenschappen". We hebben bijvoorbeeld twee veranderbare (lees-schrijf) eigenschappen die zijn gedeclareerd met de var
trefwoord: titel
en isbn
in de Boek
klasse. (Als je een opfriscursus over variabelen in Kotlin nodig hebt, bezoek dan het eerste bericht in deze reeks: Variabelen, Basistypen en Arrays).
Het verbazingwekkende is dat de getters en setters voor deze eigenschappen automatisch door de Kotlin-compiler onder de motorkap worden gegenereerd. We hebben geen zichtbaarheidsmodifiers voor deze eigenschappen opgegeven, dus deze zijn standaard openbaar. Met andere woorden, ze zijn overal toegankelijk.
Laten we naar een andere versie van dezelfde klasse in Kotlin kijken:
klasse Book constructor (titel: String, isbn: Long) var title: String var isbn: Long init this.title = title this.isbn = isbn
In deze code hebben we de secundaire constructor verwijderd. In plaats daarvan hebben we een constructor in de klassenheader a genoemd primaire constructor. Een primaire constructor heeft geen plaats om een codeblok te plaatsen, dus gebruiken we de in het
modifier om inkomende parameters van de primaire constructor te initialiseren. Merk op dat de in het
codeblok wordt onmiddellijk uitgevoerd wanneer de klasse-instantie is gemaakt.
Zoals u kunt zien, heeft onze code nog steeds veel overzicht. Laten we het verder verkleinen:
class Book constructor (var title: String, var isbn: Long)
Onze Boek
klasse is nu slechts één regel code. Dat is echt cool! Merk op dat we in de parameterlijst van de primaire constructor onze veranderbare eigenschappen hebben gedefinieerd: titel
en isbn
rechtstreeks in de primaire constructor met de var
trefwoord.
We kunnen ook standaardwaarden toevoegen aan elk van de klasse-eigenschappen in de constructor.
class Book constructor (var title: String = "default value", var isbn: Long)
In feite kunnen we ook het bouwer
zoekwoord, maar alleen als er geen zichtbaarheidsmodifier is (openbaar
, privaat
, of beschermde
) of eventuele annotaties.
class Book (var title: String = "default value", var isbn: Long)
Een heel nette klas, moet ik zeggen!
We kunnen nu een klasse-instantie zoals deze maken:
val book = Book ("Een lied van ijs en vuur", 9780007477159) val book2 = Book (1234) // gebruikt de standaardwaarde van het titelobject
In Kotlin kunnen we een eigenschap krijgen door het object van de klas boek
, gevolgd door een puntscheidingsteken .
, dan de eigenschapnaam titel
. Deze beknopte stijl van toegang tot eigenschappen wordt genoemd syntaxis voor eigendomsrechten. Met andere woorden, we hoeven niet de eigenschap getter-methode te bellen om de setter te openen of de setter te bellen om een eigenschap in Kotlin in te stellen - zoals we doen in Java.
println (book.title) // "A Song of Ice and Fire"
omdat de isbn
eigendom wordt aangegeven met de var
sleutelwoord (lezen-schrijven), we kunnen ook de eigenschapswaarde wijzigen met behulp van de toewijzingsoperator =
.
book.isbn = 1234 println (book.isbn) // 1234
Laten we nog een voorbeeld bekijken:
class Book (var title: String, val isbn: Long) val book = Book ("A Song of Ice and Fire", 9780007477159) book.isbn = 1234 // fout: alleen-lezen eigenschap book.title = "Dingen vallen uiteen "// opnieuw toegewezen titel met waarde
Hier hebben we het isbn
parameter in plaats daarvan onveranderlijk (alleen-lezen) door de. te gebruiken val
trefwoord. We hebben een klasse-instance geconcretiseerd boek
en heeft de. opnieuw toegewezen titel
bezit de waarde "Things Fall Apart". Merk op dat toen we probeerden om de isbn
eigenschapswaarde voor 1234
, de compiler klaagde. Dit komt omdat de eigenschap onveranderlijk is, te zijn gedefinieerd met de val
trefwoord.
Houd er rekening mee dat door een parameter te declareren met de var
modifier in de primaire constructor, heeft de Kotlin-compiler (achter de schermen) ons geholpen om zowel de eigenschap accessors: getter en setter te genereren. Als je gebruikt val
, het genereert alleen de vangstof.
/ * Kotlin * / class Book (var title: String, val isbn: Long)
Dit betekent dat Java-bellers het eigenschapsveld eenvoudig kunnen ophalen of instellen door respectievelijk de methode setter of getter van de eigenschap aan te roepen. Let op: dit is afhankelijk van de modifier die wordt gebruikt om de Kotlin-eigenschap te definiëren: var
of val
.
/ * Java * / Boekboek = nieuw boek ("A Song of Ice and Fire", 9780385474542) println (book.getTitle ()) // "A Song of Ice and Fire" book.setTitle ("Things Fall Apart") // stelt nieuwe waarde in println (book.getTitle ()) // "Things Fall Apart" book.getIsbn () // 9780385474542 book.setIsbn (4545454) // zal niet compileren
In deze sectie laat ik je zien hoe je aangepaste toegangen (getters en setters) voor een woning in Kotlin kunt maken als je dat wilt. Het maken van een aangepaste setter kan handig zijn als u een waarde wilt valideren of verifiëren voordat deze is ingesteld als een klasseneigenschap. En een aangepaste eigenschap-getter kan handig zijn wanneer u de waarde die moet worden geretourneerd wilt wijzigen of wijzigen.
Omdat we onze eigen aangepaste getter of setter voor een eigenschap willen maken, moeten we die eigenschap in de hoofdtekst van de klasse definiëren in plaats van de kop van de constructor.
class Book (val isbn: Long) var title = "default value"
Dit is de reden waarom we het veranderbare (lees-schrijf) hebben verplaatst titel
eigenschap in de klasse body en gaf het een standaardwaarde (anders zou het niet compileren).
class Book (val isbn: Long) var title = "default value" set (value) if (! value.isNotEmpty ()) throw IllegalArgumentException ("Titel mag niet leeg zijn") field = value
Je kunt zien dat we onze eigen settermethode hebben gedefinieerd set (waarde)
voor de titel
direct onder de eigenschapsdefinitie - merk op dat je dit niet kunt wijzigen set ()
methode handtekening, omdat dit is wat de compiler verwacht als aangepaste eigenschap setter functie.
De parameter waarde
doorgegeven aan de reeks
methode vertegenwoordigt de werkelijke waarde die door gebruikers aan de eigenschap is toegewezen - u kunt de parameternaam desgewenst wijzigen, maar waarde
heeft veel de voorkeur. We hebben het waarde
door te controleren of de waarde leeg is. Indien leeg, stop de uitvoering en gooi een uitzondering; anders de waarde opnieuw toewijzen aan een special veld-
veranderlijk.
Deze special veld-
variabel veld in de reeks
methode is een alias voor het achtergrondveld van de eigenschap: een achtergrondveld is slechts een veld dat wordt gebruikt door eigenschappen wanneer u die veldgegevens wilt wijzigen of gebruiken. anders waarde
, je kunt deze special niet hernoemen veld-
veranderlijk.
Het is heel gemakkelijk om een aangepaste getter voor een woning in Kotlin te maken.
class Book (val isbn: Long) var title = "default value" // ... set method get () return field.toUpperCase ()
Binnen in de krijgen
methode, we geven eenvoudigweg een aangepast terug veld-
-in ons geval hebben we de titel van het boek in hoofdletters teruggestuurd.
val book = Book (9780007477159) book.title = "A Song of Ice and Fire" println (book.title) // "A SONG OF ICE AND FIRE" println (book.isbn) // 9780007477159
Merk op dat elke keer dat we een waarde instellen op de titel
eigendom, zijn reeks
methode blok wordt uitgevoerd-hetzelfde geldt voor de krijgen
methode elke keer dat we het terughalen.
Als u meer wilt weten over lidfuncties voor een Kotlin-klasse (het soort functie dat is gedefinieerd in een klasse, object of interface), gaat u naar de functie Meer plezier met functies in deze serie.
Zoals ik eerder heb besproken, hebben we twee soorten constructeurs in Kotlin: primair en secundair. We hebben de vrijheid om beide in één klas te combineren, zoals u in het onderstaande voorbeeld kunt zien:
class Car (valnaam: String, val plateNo: String) var new: Boolean = true constructor (naam: String, plateNo: String, new: Boolean): this (name, plateNo) this.new = new
Merk op dat we eigenschappen niet binnen een secundaire constructor kunnen declareren, zoals we deden voor de primaire constructor. Als we dit willen doen, moeten we dit binnen het klasselichaam declareren en het dan initialiseren in de secundaire constructor.
In de bovenstaande code stellen we de standaardwaarde van de nieuwe
eigendom voor de klas Auto
(onthouden, nieuwe
is geen trefwoord in Kotlin) - we kunnen dan de secundaire constructor gebruiken om het te veranderen als we dat willen. In Kotlin moet elke secundaire constructor de primaire constructor aanroepen, of een andere secundaire constructor bellen die de primaire constructor oproept - we gebruiken de deze
sleutelwoord om dat te bereiken.
Merk ook op dat we meerdere secundaire constructors in een klasse kunnen hebben.
class Car (val name: String, val plateNo: String) var new: Boolean? = null var color: String = "" constructor (naam: String, plateNo: String, new: Boolean): this (name, plateNo) this.new = new constructor (naam: String, plateNo: String, new: Boolean , color: String): this (name, plateNo, new) this.colour = color
Als een klasse een superklasse uitbreidt, kunnen we de superklasse gebruiken super
keyword (vergelijkbaar met Java) om de constructor van de superklasse aan te roepen (we zullen overerving in Kotlin in een toekomstige post bespreken).
// roept direct de primaire constructor val car1 = Auto aan ("Peugeot 504", "XYZ234") // roept direct de 1e sec. constructor val car2 = Auto ("Peugeot 504", "XYZ234", false) // roept de laatste seconde rechtstreeks op constructor val car3 = Auto ("Peugeot 504", "XYZ234", false, "gray")
Zoals ik eerder al zei, moeten we expliciet een zichtbaarheidsmodifier toevoegen aan een constructeur in een klas bouwer
zoekwoord: constructors zijn standaard openbaar.
class Car private constructor (valnaam: String, val plateNo: String) // ...
Hier hebben we de constructor privé gemaakt. Dit betekent dat gebruikers een object niet rechtstreeks met behulp van de constructor kunnen instantiëren. Dit kan handig zijn als u wilt dat gebruikers in plaats daarvan een andere methode (een fabrieksmethode) aanroepen om onrechtstreeks objecten te maken.
In Kotlin wordt het bovenste type in de typehiërarchie aangeroepen Ieder
. Dit komt overeen met Java Voorwerp
type. Dit betekent dat alle klassen in Kotlin expliciet erven van de Ieder
type, inclusief Draad
, Int
, Dubbele
, enzovoorts. De Ieder
type bevat drie methoden: is gelijk aan
, toString
, en hashcode
.
We kunnen ook de Niets
class in Kotlin in functies die altijd een uitzondering retourneren - met andere woorden, voor functies die niet normaal eindigen. Wanneer een functie terugkeert Niets
, dan weten we dat het een uitzondering zal werpen. Geen equivalent type van deze soort bestaat op Java.
fun throwException (): Nothing throw Exception ("Uitzonderingsbericht)
Dit kan van pas komen bij het testen van foutafhandelingsgedrag in uw unit tests.
Zichtbaarheidsmodifiers helpen ons om de toegankelijkheid van onze API voor het publiek te beperken. We kunnen verschillende zichtbaarheidmodifiers leveren voor onze klassen, interfaces, objecten, methoden of eigenschappen. Kotlin biedt ons vier zichtbaarheidsmodifiers:
Dit is de standaardinstelling en elke klasse, functie, eigenschap, interface of object met deze modifier is overal toegankelijk.
Een functie, interface of klasse op het hoogste niveau die is gedeclareerd als privaat
is alleen toegankelijk binnen hetzelfde bestand.
Elke functie of eigenschap die is gedeclareerd privaat
in een klasse, object of interface kan alleen zichtbaar zijn voor andere leden van dezelfde klasse, object of interface.
class Account private val amount: Double = 0.0
De beschermde
modifier kan alleen worden toegepast op eigenschappen of functies in een klasse, object of interface. Het kan niet worden toegepast op hoofdfuncties, klassen of interfaces. Eigenschappen of functies met deze modifier zijn alleen toegankelijk binnen de klasse die deze definieert en elke subklasse.
In een project met een module (Gradle- of Maven-module), een klasse, object, interface of functie gespecificeerd met de intern
modifier gedeclareerd binnen die module is alleen toegankelijk vanuit die module.
interneklas Account val amount: Double = 0.0
Gieten betekent een object van een ander type nemen en het in een ander objecttype converteren. In Java gebruiken we bijvoorbeeld de instanceof
operator om te bepalen of een bepaald objecttype van een ander type is voordat we het vervolgens casten.
/ * Java * / if (shape instanceof Circle) Cirkelcirkel = (Cirkel) vorm; circle.calCircumference (3.5);
Zoals je kunt zien, hebben we gecontroleerd of vorm
instantie is Cirkel
, en dan moeten we expliciet de vorm
verwijzing naar a Cirkel
type zodat we methoden van de cirkel
type.
Een ander geweldig ding over Kotlin is de intelligentie van de compiler als het gaat om gieten. Laten we nu een versie in Kotlin bekijken.
/ * Kotlin * / if (vorm is Circle) shape.calCircumference (3.5)
Best netjes! De compiler is slim om te weten dat de als
blok wordt alleen uitgevoerd als de vorm
object is een instantie van Cirkel
-dus het gietmechanisme wordt voor ons onder de motorkap gedaan. We kunnen nu gemakkelijk eigenschappen of functies van de Cirkel
typ in de als
blok.
if (shape is Circle && shape.hasRadius ()) println ("Cirkelradius is shape.radius")
Hier, de laatste toestand na de &&
in de als
header wordt alleen aangeroepen als de eerste voorwaarde is waar
. Als het vorm
is geen Cirkel
, dan zal de laatste voorwaarde niet worden geëvalueerd.
We kunnen de gebruiken zoals
operator (of onveilige cast operator) om expliciet een referentie van een type naar een ander type in Kotlin te casten.
valcirkel = vorm als cirkelcirkel. calCircumference (4)
Als de expliciete castingbewerking illegaal is, houd er dan rekening mee dat a ClassCastException
zal worden gegooid. Om te voorkomen dat een uitzondering wordt gegooid tijdens het casten, kunnen we de veilige cast operator (of operator met nullable cast) zoals?
.
val cirkel: Cirkel? = vorm als? Cirkel
De zoals?
operator probeert naar het bedoelde type te casten en keert terug nul
als de waarde niet kan worden gegoten in plaats van een uitzondering te genereren. Houd er rekening mee dat een soortgelijk mechanisme is besproken in de sectie Nullability in Nullability, Loops en Voorwaarden in deze reeks. Lees daar voor een opfriscursus.
Objecten in Kotlin lijken meer op JavaScript-objecten dan Java-objecten. Merk op dat een object in Kotlin geen instantie van een specifieke klasse is!
Objecten lijken erg op klassen. Hier zijn enkele kenmerken van objecten in Kotlin:
in het
blok.Laten we nu ingaan op het maken van een object.
object Singleton fun myFunc (): Unit // do something
We plaatsen de voorwerp
sleutelwoord vóór de naam van het object dat we willen maken. In feite creëren we singletons wanneer we objecten maken in Kotlin met behulp van de voorwerp
construct, omdat er maar één exemplaar van een object bestaat. U leert hier meer over als we de objectinteroperabiliteit met Java bespreken.
Een singleton is een softwareontwerppatroon dat garandeert dat een klasse slechts één exemplaar heeft en dat die klasse een globaal toegangspunt biedt. Telkens wanneer meerdere klassen of clients de klas vragen, krijgen ze dezelfde instantie van de klas. Je kunt mijn bericht over het singleton-patroon in Java bekijken voor meer informatie.
U kunt overal in uw project toegang krijgen tot het object of singleton, zolang u het pakket importeert.
Singleton.myFunc ()
Als u een Java-coder bent, maken we meestal singletons:
openbare klasse Singleton private static Singleton INSTANCE = null; // andere instantievariabelen kunnen hier privé zijn Singleton () ; public statisch gesynchroniseerd Singleton getInstance () if (INSTANCE == null) INSTANCE = nieuwe Singleton (); return (INSTANCE); // andere instantie-methoden kunnen volgen
Zoals je kunt zien, met behulp van de Kotlin voorwerp
constructie maakt het beknopt en eenvoudiger om singletons te maken.
Objecten in Kotlin kunnen ook worden gebruikt om constanten te maken. Gewoonlijk maken we in Java constanten in een klasse door deze als een openbaar statisch laatste veld als volgt te maken:
publieke slotklasse APIConstants public static final String baseUrl = "http://www.myapi.com/"; private APIConstants ()
Deze code in Java kan op deze manier bondiger in Kotlin worden omgezet:
package com.chike.kotlin.constants object APIConstants val baseUrl: String = "http://www.myapi.com/"
Hier hebben we de constante verklaard APIConstants
met een eigendom baseurl
in een pakket com.chike.kotlin.constants
. Onder de motorkap een Java-statisch privélid baseurl
is voor ons gemaakt en geïnitialiseerd met de tekenreeks-URL.
Als u deze constante in een ander pakket in Kotlin wilt gebruiken, importeert u eenvoudigweg het pakket.
import com.chike.kotlin.constants.APIConstants APIConstants.baseUrl
Kotlin converteert een object naar een definitieve Java-klasse onder de motorkap. Deze klasse heeft een eigen statisch veld AANLEG
die een enkele instantie (een singleton) van de klas bevat. De volgende code laat zien hoe eenvoudig gebruikers een Kotlin-object vanuit Java kunnen bellen.
/ * Java * / Singleton.INSTANCE.myFunc ()
Hier, een Java-klasse genoemd eenling
werd gegenereerd met een openbaar statisch definitief lid AANLEG
, inclusief een publieke eindfunctie myFunc ()
.
Om de objectfunctie of -eigenschap in Kotlin een statisch lid van de gegenereerde Java-klasse te maken, gebruiken we de @JvmStatic
annotatie. Hier is hoe het te gebruiken:
object Singleton @JvmStatic fun myFunc (): Unit // do something
Door de @JvmStatic
annotatie aan myFunc ()
, de compiler heeft het omgezet in een statische functie.
Nu kunnen Java-bellers het noemen als een normale statische lid-oproep. Merk op dat het gebruik van de AANLEG
statische velden om leden te bellen, werken nog steeds.
/ * Java * / Singleton.myFunc ()
Nu hebben we begrepen welke objecten in Kotlin zijn, laten we duiken in een ander soort objecten die metgezelobjecten worden genoemd.
Omdat Kotlin geen statische klassen, methoden of eigenschappen ondersteunt zoals die we op Java hebben, heeft het Kotlin-team ons een krachtiger alternatief geboden, genaamd metgezel objecten. Een begeleidend object is in feite een object dat tot een klasse behoort - deze klasse staat bekend als de begeleidende klasse van het object. Dit betekent ook dat de kenmerken die ik heb genoemd voor objecten ook van toepassing zijn op begeleidende objecten.
Net als bij statische methoden in Java, is een begeleidend object niet gekoppeld aan een klasse-instantie maar eerder aan de klasse zelf, bijvoorbeeld een statische methode in de fabriek, die de taak heeft om een klasse-instantie te maken.
class Persoon private constructor (var firstName: String, var lastName: String) companion-object fun create (firstName: String, lastName: String): Person = Person (firstName, lastName)
Hier hebben we de constructeur gemaakt privaat
-dit betekent dat gebruikers buiten de klasse geen instantie rechtstreeks kunnen maken. In ons bijbehorende objectblok hebben we een functie create ()
, welke een creëert Persoon
object en retourneert het.
metgezel
object-instantiatie is lui. Met andere woorden, het zal de eerste keer alleen worden geïnstantieerd wanneer dit nodig is. De instantiatie van een metgezel
object gebeurt wanneer een instantie van de metgezel
klasse is gemaakt of de metgezel
objectleden worden benaderd.
Laten we eens kijken hoe een metgezel-objectfunctie in Kotlin op te roepen.
val person = Person.create ("Cersei", "Lannister") println (person.firstName) // print "Cersei"
Zoals u kunt zien, is dit hetzelfde als een normale statische methode in Java aanroepen. Met andere woorden, we bellen gewoon de klas en bellen dan het lid. Merk op dat we naast functies ook eigenschappen kunnen hebben in ons begeleidende object.
class Persoon private constructor (var firstName: String, var lastName: String) init count ++ begeleidende object var count: Int = 0 fun create (firstName: String, lastName: String): Person = Person (firstName, lastName) init println ("Persoonsobject gemaakt")
Merk ook op dat de metgezel
klasse heeft onbeperkte toegang tot alle eigenschappen en functies die zijn gedeclareerd in het bijbehorende object, terwijl een bijbehorend object geen toegang heeft tot de klasleden. We kunnen een hebben in het
codeblok binnen een metgezel
object - dit wordt onmiddellijk aangeroepen wanneer het begeleidende object wordt gemaakt.
Person.create ("Arya", "Stark") Person.create ("Daenerys", "Targaryen") println (Person.count)
Het resultaat van het uitvoeren van de bovenstaande code is:
Persoon begeleidend object gemaakt 2
Onthoud, slechts één instantie van een klasse metgezel
object kan ooit bestaan.
We zijn ook vrij om ons begeleidende object een naam te geven.
// ... begeleidende object Factory var count: Int = 0 fun create (firstName: String, lastName: String): Person = Person (firstName, lastName) // ...
Hier hebben we het een naam gegeven Fabriek
. We kunnen het zo in Kotlin noemen:
Person.Factory.create ("Petyr", "Baelish")
Deze stijl is breedsprakig, dus het houden van de vorige manier heeft veel de voorkeur. Maar dit kan van pas komen als u een bijbehorende objectfunctie of eigenschap vanuit Java aanroept.
Zoals eerder gezegd, zoals objecten, kunnen begeleidende objecten ook eigenschappen of functies bevatten, interfaces implementeren en zelfs een klasse uitbreiden.
interface PersonFactory fun create (firstName: String, lastName: String): Person class Person private constructor (var firstName: String, var lastName: String) companion object: PersonFactory overschrijven leuk maken (firstName: String, lastName: String) : Persoon retourpersoon (firstName, lastName)
Hier hebben we een interface PersonFactory
met slechts een single create ()
functie. Kijkend naar onze nieuwe gewijzigd metgezel
object, implementeert het nu deze interface (je leert in een later bericht over interfaces en overerving in Kotlin).
Onder de motorkap worden vergelijkbare objecten gecompileerd op dezelfde manier als waarop een Kotlin-object is gecompileerd. In ons eigen geval worden er twee klassen voor ons gegenereerd: een finale Persoon
klasse en een innerlijke statische eindklasse Persoon $ Companion
.
De Persoon
klasse bevat een laatste statisch lid genaamd Metgezel
-dit statische veld is een object van de Persoon $ Companion
innerlijke klasse. De Persoon $ Companion
innerlijke klasse heeft ook zijn eigen leden, en een van hen is een publieke finale functie genaamd create ()
.
Merk op dat we ons begeleidende object geen naam hebben gegeven, dus de gegenereerde statische innerlijke klasse was Metgezel
. Als we het een naam hadden gegeven, dan zou de gegenereerde naam de naam zijn die we hem in Kotlin hebben gegeven.
/ * Java * / Person persoon = Person.Companion.create ("Jon", "Snow");
Hier heeft het metgezelobject in Kotlin geen naam, dus gebruiken we de naam Metgezel
geleverd door de compiler voor Java-bellers om het te bellen.
De @JvmStatic
annotatie toegepast op een begeleidend objectlid werkt op dezelfde manier als hoe het werkt voor een gewoon object.
Op dezelfde manier als uitbreidingsfuncties de functionaliteit van een klasse kunnen uitbreiden, kunnen we ook de functionaliteit van een begeleidend object uitbreiden. (Als je een opfriscursus op uitbreidingsfuncties in Kotlin wilt, bezoek dan de tutorial Advanced Functions in deze reeks).
class ClassA companion object fun ClassA.Companion.extFunc () // ... do implementation ClassA.extFunc ()
Hier hebben we een uitbreidingsfunctie gedefinieerd extFunc ()
op het bijbehorende object ClassA.Companion
. Met andere woorden, extfunc ()
is een extensie van het bijbehorende object. Dan kunnen we de extensie bellen alsof het een ledenfunctie is (het is niet!) Van het bijbehorende object.
Achter de schermen zal de compiler een statische utiliteitsfunctie creëren extFunc ()
. Het receiver-object als argument voor deze utiliteitsfunctie is ClassA $ Companion
.
In deze tutorial leer je over basislessen en objecten in Kotlin. We hebben het volgende behandeld over klassen:
Ook heb je geleerd hoe objecten en bijbehorende objecten in Kotlin je statische methoden, constanten en singletons die je in Java codeert, gemakkelijk kunnen vervangen. Maar dat is niet alles! Er is nog meer te leren over lessen in Kotlin. In het volgende bericht laat ik je nog meer coole functies zien die Kotlin heeft voor objectgeoriënteerd programmeren. Tot ziens!
Voor meer informatie over de Kotlin-taal, raad ik aan de Kotlin-documentatie te bezoeken. Of bekijk enkele van onze andere Android-apps voor app-ontwikkeling hier op Envato Tuts+!