Om du är en erfaren Android-applikationsutvecklare, har du förmodligen använt Java-verbaliteten 7. Som ett resultat kan du hitta Kotlins korta syntax, som är inriktad på funktionella programmerare, något oroande.
Ett vanligt problem som nybörjare möter när du lär dig Kotlin förstår hur man förväntar dig att arbeta med Java-gränssnitt som innehåller en enda metod. Sådana gränssnitt är allestädes närvarande i Android-världen och kallas ofta SAM-gränssnitt, där SAM är kortfattat för Single Abstract Method.
I den här korta handledningen lär du dig allt du behöver veta för att använda Java: s SAM-gränssnitt i Kotlin-kod.
När du vill använda ett Java-gränssnitt som innehåller en enda metod i din Kotlin-kod behöver du inte manuellt skapa en anonym klass som implementerar den. I stället kan du använda ett lambda-uttryck. Tack vare en process som kallas SAM-konvertering kan Kotlin omvandla alla lambda-uttryck vars signatur matchar gränssnittets enda metod till en instans av en anonym klass som implementerar gränssnittet.
Tänk till exempel följande Java-gränssnitt för en metod:
offentligt gränssnitt Adder public void add (int a, int b);
Ett naivt och Java 7-liknande tillvägagångssätt för att använda ovanstående gränssnitt skulle innebära att man arbetar med en objekt
uttryck och skulle se ut så här:
// Skapa instans av en anonym klass // med hjälp av objektets nyckelord val adder = objekt: Adder överrätta rolig tillägg (a: Int, b: Int): Int return a + b
Det är en massa onödig kod, som inte heller är mycket läsbar. Genom att utnyttja Kotlins SAM-konverteringsfacilitet kan du dock skriva följande ekvivalenta kod istället:
// Skapa instans med en lambda val adder = Adder a, b -> a + b
Som du kan se har vi nu ersatt den anonyma klassen med ett kort lambda-uttryck, som är prefixat med namnet på gränssnittet. Observera att antalet argumenter som lambda-uttrycket tar är lika med antalet parametrar i signaturen för gränssnittets metod.
När du arbetar med Java-klasser som har metoder som tar SAM-typer som deras argument kan du förenkla ovanstående syntax ytterligare. Tänk på följande Java-klass, som innehåller en metod som förväntar sig ett objekt som implementerar Huggorm
gränssnitt:
offentlig klass Calculator privat adder adder; public void setAdder (adder adder) this.adder = adder; public void add (int a, int b) Log.d ("CALCULATOR", "Sum är" + adder.add (a, b));
I din Kotlin-kod kan du nu direkt skicka ett lambda-uttryck till setAdder ()
metod, utan att prefixa den med namnet på Huggorm
gränssnitt.
val kalkylator = Kalkylator () calculator.setAdder (a, b -> a + b)
Det är värt att notera att medan du ringer en metod som tar en SAM-typ som enda argument, kan du hoppa över parentesen för att göra koden ännu mer kortfattad.
calculator.setAdder a, b -> a + b
Om du tycker att lambda-uttryck är förvirrande, har jag goda nyheter för dig: SAM-konverteringar fungerar också bra med vanliga funktioner. Tänk till exempel följande funktion vars underskrift matchar den för Huggorm
gränssnittets metod:
roligt myCustomAdd (a: Int, b: Int): Int = if (a + b < 100) -1 else if (a+b < 200) 0 else a+b
Kotlin låter dig direkt passera myCustomAdd ()
fungera som ett argument till setAdder ()
metod för Kalkylator
klass. Glöm inte att referera till metoden med hjälp av ::
operatör. Här är hur:
calculator.setAdder (detta :: myCustomAdd)
Det
VariabelMånga gånger innehåller SAM-gränssnitt enparametermetoder. En metod med en parameter, som namnet antyder, har bara en parameter i dess signatur. Medan du arbetar med sådana gränssnitt, tillåter Kotlin dig att släppa parametern i ditt lambda-uttrycks signatur och använda en implicit variabel som heter Det
i uttryckets kropp. För att göra saker tydligare, överväga följande Java-gränssnitt:
public interface Doubler public int doubleIt (int nummer);
Medan du använder Doubler
gränssnittet i din Kotlin-kod, behöver du inte uttryckligen nämna siffra
parameter i ditt lambda uttrycks signatur. Istället kan du helt enkelt referera till det som Det
.
// Detta lambda uttryck använder variabeln val doubler1 = Doubler 2 * it // motsvarar detta vanliga lambda uttryck val doubler2 = Doubler number -> 2 * number
Som Java-utvecklare kan du vara benägen att skapa SAM-gränssnitt i Kotlin. Att göra det är dock vanligtvis inte en bra idé. Om du skapar ett SAM-gränssnitt i Kotlin, eller skapar en Kotlin-metod som förväntar dig att ett objekt implementerar ett SAM-gränssnitt som ett argument, kommer SAM-konverteringsanläggningen inte att vara tillgänglig för dig. SAM-omvandling är en Java-kompatibilitetsfunktion och är begränsad till Java klasser och gränssnitt bara.
Eftersom Kotlin stöder högre orderfunktioner som kan ta andra funktioner som argument, behöver du aldrig skapa SAM-gränssnitt i det. Till exempel, om Kalkylator
klassen är omskriven i Kotlin, dess setAdder ()
Metoden kan skrivas så att den direkt tar en funktion som sitt argument, istället för ett objekt som implementerar Huggorm
gränssnitt.
klassen kalkylator var adder: (a: Int, b: Int) -> Int = a, b -> 0 // Standard implementering // Setter är tillgänglig som standard roligt tillägg (a: Int, b: Int) Log.d ("CALCULATOR", "Summa" + adder (a, b))
Medan du använder ovanstående klass kan du ställa in huggorm
till en funktion eller ett lambda uttryck med hjälp av =
operatör. Följande kod visar hur:
val kalkylator = Kalkylator () calculator.adder = detta :: myCustomAdd // ELLER calculator.adder = a, b -> a + b
Android APIs skrivs till stor del i Java, och många använder SAM-gränssnitt i stor utsträckning. Detsamma kan sägas om de flesta tredje partsbiblioteken också. Genom att använda de tekniker du lärde dig i den här handledningen kan du arbeta med dem i din Kotlin-kod på ett kortfattat och lättläst sätt.
För mer information om Kotlins Java-kompatibilitetsfunktioner, se den officiella dokumentationen. Och kolla in några av våra andra handledning på Android App-utveckling!