Java Academy · leksjon

Egendefinerte funksjonelle grensesnitt

Definer ditt eget med @FunctionalInterface

Leksjon 4 av 413 trinn

Egendefinerte funksjonelle grensesnitt er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.

Hva som gjør et grensesnitt funksjonelt

Et funksjonelt grensesnitt har nøyaktig én abstrakt metode (SAM). Det er denne ene metoden en lambda implementerer.

  • Default- og statiske metoder teller ikke med i grensen.
interface Greeter {
    String greet(String name);
}

public class Main {
    public static void main(String[] args) {
        Greeter g = name -> "Hello, " + name;
        System.out.println(g.greet("Ada"));
    }
}

Annotasjonen @FunctionalInterface

@FunctionalInterface ber kompilatoren håndheve regelen om én abstrakt metode. Hvis De ved et uhell legger til en ekstra abstrakt metode, mislykkes kompileringen.

@FunctionalInterface
interface Calculator {
    int compute(int a, int b);
}

public class Main {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        System.out.println(add.compute(3, 4));
    }
}

Hvorfor annotasjonen er nyttig

Annotasjonen dokumenterer hensikten og beskytter kontrakten. Uten den fungerer grensesnittet fortsatt som et funksjonelt grensesnitt, men en kollega kan ødelegge dette ved å legge til en abstrakt metode til.

@FunctionalInterface
interface Transformer {
    String apply(String input);
}

public class Main {
    public static void main(String[] args) {
        Transformer reverse = s -> new StringBuilder(s).reverse().toString();
        System.out.println(reverse.apply("abc"));
    }
}

Egendefinert grensesnitt med generiske typer

Grensesnittet Deres kan være generisk, akkurat som de innebygde grensesnittene.

@FunctionalInterface
interface Converter<S, T> {
    T convert(S source);
}

public class Main {
    public static void main(String[] args) {
        Converter<String, Integer> toInt = Integer::parseInt;
        System.out.println(toInt.convert("123") + 1);
    }
}

Default-metoder er tillatt

Et funksjonelt grensesnitt kan ha default-metoder. De legger til funksjonalitet uten å bryte regelen om én abstrakt metode.

@FunctionalInterface
interface Operation {
    int apply(int x);

    default Operation then(Operation next) {
        return x -> next.apply(this.apply(x));
    }
}

public class Main {
    public static void main(String[] args) {
        Operation inc = x -> x + 1;
        Operation dbl = x -> x * 2;
        System.out.println(inc.then(dbl).apply(5));
    }
}

Statiske metoder er også tillatt

Statiske metoder kan fungere som fabrikkmetoder, på samme måte som Function.identity().

@FunctionalInterface
interface Mapper {
    int map(int x);

    static Mapper identity() {
        return x -> x;
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Mapper.identity().map(99));
    }
}

Kaste checked-unntak

Hvis den abstrakte metoden Deres deklarerer et checked-unntak, kan lambdaen kaste det. Den innebygde Function kan ikke gjøre dette, noe som er én grunn til å definere et eget grensesnitt.

@FunctionalInterface
interface RiskyParser {
    int parse(String s) throws NumberFormatException;
}

public class Main {
    public static void main(String[] args) {
        RiskyParser p = Integer::parseInt;
        System.out.println(p.parse("77"));
    }
}

Sende egendefinerte grensesnitt til metoder

Grensesnittet Deres blir en parametertype som lar kallere levere funksjonalitet via lambdauttrykk.

@FunctionalInterface
interface IntCombiner {
    int combine(int a, int b);
}

public class Main {
    static int reduce(int[] arr, IntCombiner c) {
        int acc = arr[0];
        for (int i = 1; i < arr.length; i++) acc = c.combine(acc, arr[i]);
        return acc;
    }

    public static void main(String[] args) {
        int[] data = {1, 2, 3, 4};
        System.out.println(reduce(data, (a, b) -> a + b));
    }
}

Grensesnitt med tre argumenter

JDK-et leveres bare med grensesnitt for ett og to argumenter. For tre eller flere argumenter må De definere et eget.

@FunctionalInterface
interface TriFunction<A, B, C, R> {
    R apply(A a, B b, C c);
}

public class Main {
    public static void main(String[] args) {
        TriFunction<Integer, Integer, Integer, Integer> sum3 = (a, b, c) -> a + b + c;
        System.out.println(sum3.apply(1, 2, 3));
    }
}

Metodereferanser passer til egendefinerte grensesnitt

Alle metoder med en signatur som samsvarer med SAM-en, kan leveres som en metodereferanse.

@FunctionalInterface
interface StringTest {
    boolean check(String s);
}

public class Main {
    public static void main(String[] args) {
        StringTest blank = String::isBlank;
        System.out.println(blank.check("   "));
    }
}

Anonym klasse kontra lambda

En lambda er en konsis erstatning for en anonym klasse som implementerer et funksjonelt grensesnitt. Begge gir samme funksjonalitet.

@FunctionalInterface
interface Action {
    void run();
}

public class Main {
    public static void main(String[] args) {
        Action old = new Action() {
            public void run() { System.out.println("anonymous"); }
        };
        Action neo = () -> System.out.println("lambda");
        old.run();
        neo.run();
    }
}

Kort kontroll

Hva garanterer @FunctionalInterface?

Oppsummering

De definerte egne funksjonelle grensesnitt:

  • Et funksjonelt grensesnitt har nøyaktig én abstrakt metode (SAM).
  • @FunctionalInterface håndhever denne regelen ved kompilering.
  • Default- og statiske metoder, generiske typer og checked-unntak er alle tillatt.
  • Egendefinerte grensesnitt dekker behov som JDK-et ikke dekker, for eksempel funksjoner med tre argumenter eller lambdaer som kaster checked-unntak.
Gratis å komme i gang

Lær deg Java med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
104
Leksjoner
374

Ofte stilte spørsmål

Er leksjonen «Egendefinerte funksjonelle grensesnitt» gratis?

Ja – hele teksten i «Egendefinerte funksjonelle grensesnitt» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Egendefinerte funksjonelle grensesnitt»?

Definer ditt eget med @FunctionalInterface Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Java Academy?

Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Egendefinerte funksjonelle grensesnitt»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?

Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Function og BiFunction
  2. Supplier og Consumer
  3. Predicate og komposisjon
  4. Egendefinerte funksjonelle grensesnitt
← Tilbake til Java Academy