web-dev-qa-db-fra.com

Définition précise de l'interface fonctionnelle en Java 8

Récemment, j'ai commencé à explorer Java 8 et je ne comprends pas très bien le concept d '"interface fonctionnelle" essentiel à la mise en oeuvre par Java des expressions lambda. Il existe un un guide assez complet aux fonctions lambda en Java, mais je me suis retrouvé coincé sur le chapitre qui définit le concept d'interfaces fonctionnelles . La définition se lit comme suit:

Plus précisément, une interface fonctionnelle est définie comme toute interface ayant exactement une méthode abstraite.

Puis il passe aux exemples, dont l’un est Comparator interface:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
} 

J'ai pu tester que je pouvais utiliser une fonction lambda à la place de l'argument Comparator et que cela fonctionne (c'est-à-dire Collections.sort(list, (a, b) -> a-b)). 

Mais dans l'interface du comparateur, les deux méthodes compare et equals sont abstraites, ce qui signifie qu'elles ont deux méthodes abstraites . Alors, comment cela peut-il fonctionner si la définition nécessite une interface avec exactement une méthode abstraite ? Qu'est-ce que j'oublie ici?

62
Anton Cherkashyn

Depuis la même page à laquelle vous avez accédé

L'interface Comparator est fonctionnelle car, bien qu'elle déclare deux méthodes abstraites, l'une d'entre elles, égale à, a une signature correspondant à une méthode publique dans Object. Les interfaces déclarent toujours les méthodes abstraites correspondant aux méthodes publiques de Object, mais le font généralement de manière implicite. Qu'elles soient déclarées implicitement ou explicitement, ces méthodes sont exclues du compte.

Je ne peux pas vraiment dire mieux.

Edit: Mis à jour au texte le plus récent de cette page, par le commentaire de Maurice (merci!)

55
Mark Peters

Une autre explication est donnée dans la page @FunctionalInterface :

Conceptuellement, une interface fonctionnelle a exactement une méthode abstraite. Les méthodes par défaut ayant une implémentation, elles ne sont pas abstraites. Si une interface déclare une méthode abstraite substituant l'une des méthodes publiques de Java.lang.Object, cela ne compte pas non plus dans le nombre de méthodes abstraites de l'interface, car toute implémentation de l'interface aura une implémentation à partir de Java.lang.Object ou ailleurs.

Vous pouvez tester quelle interface est une interface fonctionnelle correcte en utilisant @FunctionalInterface.

Par exemple.:

  • cela marche

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals(Object o);
    
    }
    
  • cela génère une erreur:

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals();
    
    }
    

    Plusieurs méthodes abstraites non dérogatoires trouvées dans l'interface FunctionalInterf

7
ROMANIA_engineer

Q. Mais dans l'interface du comparateur, les méthodes de comparaison () et d'égal () sont abstraites, ce qui signifie qu'il existe deux méthodes abstraites. Alors, comment cela peut-il fonctionner si la définition nécessite une interface pour avoir exactement une méthode abstraite? Qu'est-ce que j'oublie ici?

UNE.

Une interface fonctionnelle peut spécifier toute méthode publique définie par Object, telle que equals (), Sans affecter son statut «d'interface fonctionnelle». Les méthodes Object publiques sont considérées comme membres Implicites d'une interface fonctionnelle, car elles sont automatiquement implémentées par une instance d'une interface fonctionnelle .

3
Aniket Thakur

La documentation Java dit:

Notez qu'il est toujours prudent de ne pas remplacer Object.equals (Object). Toutefois, cette méthode peut, dans certains cas, améliorer les performances de En permettant aux programmes de déterminer que deux distincts. .] les comparateurs imposent le même ordre.

Peut-être que Comparator est spécial? Peut-être, même si c'est une interface, il y a une implémentation par défaut de equals() qui appelle compare()? Algorithmiquement, c'est trivial.

Je pensais que toutes les méthodes déclarées dans les interfaces étaient abstraites (c'est-à-dire sans implémentation par défaut). Mais peut-être que je manque quelque chose.

0
Seva Alekseyev

Définition:

Si une interface ne contient qu'une seule méthode abstraite, ce type d'interface est appelé interface fonctionnelle.

Utilisation:

  1. Une fois que nous avons écrit l'expression Lambda "->" pour appeler sa fonctionnalité, , Dans ce contexte, nous avons besoin de l'interface fonctionnelle.
  2. Nous pouvons utiliser la référence d'interface fonctionnelle pour faire référence à l'expression Lambda .
  3. Dans l'interface fonctionnelle, nous pouvons avoir une méthode abstraite et n Nombre de méthodes par défaut/statiques.

Interface fonctionnelle en matière d'héritage:

Si une interface étend l'interface fonctionnelle et que l'interface enfant ne contient aucune méthode abstraite, l'interface enfant est également considérée comme une interface fonctionnelle.

L'interface fonctionnelle n'est pas nouvelle en Java, elle est déjà utilisée dans les API suivantes:

  1. Runnable: contient la méthode run () uniquement.
  2. Callable: contient la méthode call () uniquement.
  3. Comparable: contient uniquement la méthode compareTo ().
0
Eswaran Venkatesan

Avant Java 8, une interface ne pouvait déclarer qu'une ou plusieurs méthodes, également appelées méthode abstraite (méthode sans implémentation, uniquement la signature). À partir de Java 8, une interface peut également implémenter une ou plusieurs méthodes (appelée méthode par défaut d'interface) et des méthodes statiques ainsi que des méthodes abstraites. Les méthodes d'interface par défaut sont marquées comme mot clé.

La question est donc: qu'est-ce qu'une interface fonctionnelle? Une interface avec une méthode abstraite unique (SAM) est appelée interface fonctionnelle.

Ce qui signifie - 

  1. Une interface avec Single Abstract Method est une interface fonctionnelle
  2. Une interface avec une méthode abstraite unique et zéro ou plusieurs méthodes par défaut Et une méthode statique zéro ou plus constitue également une interface fonctionnelle Valide.

Plus de détails avec l'exemple de code https://readtorakesh.blogspot.com/2018/08/functional-interface-Java8.html

0
Rakesh Prajapati