0Pricing
Java Academy · Leçon

Interfaces fonctionnelles personnalisées

Définissez la vôtre avec @FunctionalInterface

Interfaces fonctionnelles personnalisées est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Qu’est-ce qui rend une interface fonctionnelle

Une interface fonctionnelle possède exactement une méthode abstraite (SAM). C’est cette méthode unique qu’implémente une lambda.

  • Les méthodes par défaut et statiques ne sont pas prises en compte dans cette limite.
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"));
    }
}

L’annotation @FunctionalInterface

@FunctionalInterface demande au compilateur de faire respecter la règle de la méthode abstraite unique. Si vous ajoutez accidentellement une deuxième méthode abstraite, la compilation échoue.

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

Pourquoi l’annotation est utile

L’annotation documente l’intention et protège le contrat. Sans elle, l’interface reste fonctionnelle, mais un collègue pourrait la rendre non conforme en ajoutant une autre méthode abstraite.

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

Interface personnalisée avec des génériques

Votre interface peut être générique, tout comme les interfaces intégrées.

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

Les méthodes par défaut sont autorisées

Une interface fonctionnelle peut posséder des méthodes default. Elles ajoutent un comportement sans enfreindre la règle de la méthode abstraite unique.

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

Les méthodes statiques sont également autorisées

Les méthodes statiques peuvent servir de fabriques, comme 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));
    }
}

Lever des exceptions contrôlées

Si votre méthode abstraite déclare une exception contrôlée, la lambda peut la lever. La Function intégrée ne le permet pas, ce qui constitue l’une des raisons de définir votre propre interface.

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

Passer des interfaces personnalisées aux méthodes

Votre interface devient un type de paramètre, ce qui permet aux appelants de fournir un comportement au moyen de lambdas.

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

Interface à trois arguments

Le JDK fournit uniquement des interfaces à un ou deux arguments. Pour trois arguments ou davantage, définissez votre propre interface.

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

Les références de méthodes s’adaptent aux interfaces personnalisées

Toute méthode dont la signature correspond à la SAM peut être fournie comme référence de méthode.

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

Classe anonyme ou lambda

Une lambda remplace de façon concise une classe anonyme qui implémente une interface fonctionnelle. Les deux produisent le même comportement.

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

Vérification rapide

Que garantit @FunctionalInterface ?

Récapitulatif

Vous avez défini vos propres interfaces fonctionnelles :

  • Une interface fonctionnelle possède exactement une méthode abstraite (SAM).
  • @FunctionalInterface impose cette règle lors de la compilation.
  • Les méthodes par défaut et statiques, les génériques et les exceptions contrôlées sont tous autorisés.
  • Les interfaces personnalisées comblent les lacunes que le JDK ne couvre pas, comme les fonctions à trois arguments ou les lambdas qui lèvent des exceptions contrôlées.

Questions Fréquemment Posées

La leçon « Interfaces fonctionnelles personnalisées » est-elle gratuite ?

Oui — le texte complet de « Interfaces fonctionnelles personnalisées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Interfaces fonctionnelles personnalisées » ?

Définissez la vôtre avec @FunctionalInterface Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Interfaces fonctionnelles personnalisées » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Function et BiFunction
  2. Supplier et Consumer
  3. Predicate et composition
  4. Interfaces fonctionnelles personnalisées
← Retour à Java Academy