Java Academy · Lektion

Brugerdefinerede funktionelle interfaces

Definér Deres eget med @FunctionalInterface

Lektion 4 af 413 trin

Brugerdefinerede funktionelle interfaces er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad gør en grænseflade funktionel

En funktionel grænseflade har præcis én abstrakt metode (SAM). Det er denne ene metode, som en lambda implementerer.

  • Default- og statiske metoder tæller ikke med i grænsen.
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"));
    }
}

Annoteringen @FunctionalInterface

@FunctionalInterface fortæller compileren, at den skal håndhæve reglen om én abstrakt metode. Hvis du ved et uheld tilføjer endnu en 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));
    }
}

Derfor er annoteringen nyttig

Annoteringen dokumenterer hensigten og beskytter kontrakten. Uden den fungerer grænsefladen stadig som en funktionel grænseflade, men en kollega kan ødelægge den ved at tilføje endnu en abstrakt metode.

@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"));
    }
}

Brugerdefineret grænseflade med generiske typer

Din grænseflade kan være generisk, ligesom de indbyggede grænseflader.

@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 tilladt

En funktionel grænseflade må have default-metoder. De tilføjer funktionalitet uden at bryde reglen 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å tilladt

Statiske metoder kan fungere som fabriksmetoder på samme måde 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));
    }
}

Udløsning af kontrollerede undtagelser

Hvis din abstrakte metode angiver en kontrolleret undtagelse, må lambdaen udløse den. Den indbyggede Function kan ikke gøre dette, hvilket er en af grundene til at definere din egen.

@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"));
    }
}

Overførsel af brugerdefinerede grænseflader til metoder

Din grænseflade bliver en parametertype, så kaldere kan levere adfærd via lambdaer.

@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));
    }
}

Grænseflade med tre argumenter

JDK indeholder kun grænseflader med ét eller to argumenter. Hvis du har brug for tre eller flere argumenter, skal du definere din egen.

@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));
    }
}

Metodereferencer passer til brugerdefinerede grænseflader

Enhver metode, hvis signatur matcher SAM, kan leveres som en metodereference.

@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 kortfattet erstatning for en anonym klasse, der implementerer en funktionel grænseflade. Begge dele giver den samme adfærd.

@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();
    }
}

Hurtigt tjek

Hvad garanterer @FunctionalInterface?

Opsamling

Du definerede dine egne funktionelle grænseflader:

  • En funktionel grænseflade har præcis én abstrakt metode (SAM).
  • @FunctionalInterface håndhæver reglen ved kompilering.
  • Default- og statiske metoder, generiske typer og kontrollerede undtagelser er alle tilladt.
  • Brugerdefinerede grænseflader udfylder huller, som JDK ikke dækker, f.eks. funktioner med tre argumenter eller lambdaer med kontrollerede undtagelser.
Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “Brugerdefinerede funktionelle interfaces” gratis?

Ja — hele teksten til “Brugerdefinerede funktionelle interfaces” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Brugerdefinerede funktionelle interfaces”?

Definér Deres eget med @FunctionalInterface Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Brugerdefinerede funktionelle interfaces”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Function og BiFunction
  2. Supplier og Consumer
  3. Predicate og komposition
  4. Brugerdefinerede funktionelle interfaces
← Tilbage til Java Academy