interface enhancements java 8 java functional interface
Ce tutoriel explique les ajouts à l'interface dans Java 8 et les différences entre les concepts Java tels qu'une classe abstraite, un mot-clé étend, etc. avec les interfaces:
Nous avons tout exploré Interfaces en Java dans notre dernier tutoriel. Nous avons présenté et couvert les concepts de base des interfaces en Java, y compris les multiples interfaces.
Avant Java 8, les interfaces étaient autorisées à n'avoir que des méthodes abstraites et des variables statiques et finales. Les méthodes abstraites sont par défaut publiques et doivent être remplacées par la classe qui implémente une interface.
L'interface était donc principalement un contrat et n'était impliquée qu'avec des méthodes constantes (statiques et finales) et abstraites.
=> Jetez un œil au guide du débutant Java ici.
Ce que vous apprendrez:
- Modifications des interfaces dans Java 8
- Interfaces fonctionnelles Java 8
- Interface de classe Vs en Java
- Java étend ses implémentations
- Interface vs classe abstraite en Java
- Conclusion
Modifications des interfaces dans Java 8
La version Java 8 introduit ou nous permet d'avoir des méthodes statiques et par défaut dans les interfaces. En utilisant les méthodes par défaut dans une interface, les développeurs peuvent ajouter plus de méthodes aux interfaces. De cette façon, ils ne perturbent ni ne modifient les classes qui implémentent l'interface.
Java 8 permet également à l'interface d'avoir une méthode statique. Les méthodes statiques sont les mêmes que celles que nous définissons dans les classes. Notez que la méthode statique ne peut pas être remplacée par la classe qui implémente l'interface.
L'introduction de méthodes statiques et par défaut dans l'interface a facilité la modification des interfaces sans aucun problème et a également rendu les interfaces plus faciles à implémenter.
Java 8 introduit également des «expressions Lambda» dans les interfaces fonctionnelles. En outre, à partir de Java 8, d'autres interfaces fonctionnelles intégrées ont été ajoutées à Java.
Dans ce didacticiel, nous discuterons de tous ces ajouts aux interfaces de Java 8 et discuterons également de certaines des différences entre divers concepts Java tels que les classes abstraites, le mot-clé extend, etc. avec les interfaces.
Méthode statique dans l'interface en Java
Les interfaces peuvent également avoir des méthodes qui peuvent avoir des définitions. Ce sont les méthodes statiques de l'interface. Les méthodes statiques sont définies dans l'interface et elles ne peuvent pas être remplacées ou modifiées par les classes qui implémentent cette interface.
Nous pouvons appeler ces méthodes statiques en utilisant directement le nom de l'interface.
L'exemple suivant illustre l'utilisation de la méthode statique.
//interface declaration interface TestInterface { // static method definition static void static_print() { System.out.println('TestInterface::static_print ()'); } // abstract method declaration void nonStaticMethod(String str); } // Interface implementation class TestClass implements TestInterface { // Override interface method @Override public void nonStaticMethod(String str) { System.out.println(str); } } public class Main{ public static void main(String() args) { TestClass classDemo = new TestClass(); // Call static method from interface TestInterface.static_print(); // Call overridden method using class object classDemo.nonStaticMethod('TestClass::nonStaticMethod ()'); } }
Production:
Le programme ci-dessus a une TestInterface. Il possède une méthode statique nommée «static_print» et également une méthode non statique nommée nonstaticmethod.
Nous avons implémenté TestInterface dans TestClass et remplacé nonStaticMethod. Ensuite, dans la méthode principale, nous appelons la méthode static_print directement en utilisant TestInterface et nonStaticMethod en utilisant l'objet de TestClass.
Méthode par défaut de l'interface
Comme déjà mentionné, les interfaces antérieures à Java 8 n'autorisaient que des méthodes abstraites. Ensuite, nous fournirions cette implémentation de méthode dans une classe séparée. Si nous devions ajouter une nouvelle méthode à l'interface, nous devons alors fournir son code d'implémentation dans la même classe.
Par conséquent, si nous modifions l'interface en y ajoutant une méthode, la classe d'implémentation changerait également.
Cette limitation a été surmontée par la version Java 8 qui permettait aux interfaces d'avoir des méthodes par défaut. Les méthodes par défaut fournissent en quelque sorte une compatibilité descendante avec les interfaces existantes et nous n'avons pas besoin de modifier la classe d'implémentation. Les méthodes par défaut sont également appelées «méthode d'extension virtuelle» ou «méthodes de défense».
Les méthodes par défaut sont déclarées en utilisant le mot-clé «default» dans la déclaration. La déclaration est suivie de la définition de la méthode. Nous pouvons remplacer la méthode par défaut car elle est disponible pour la classe qui implémente l'interface.
De la même manière, nous pouvons l'invoquer en utilisant directement l'objet de classe d'implémentation depuis l'interface sans le remplacer.
interface TestInterface { // abstract method public void cubeNumber(int num); // default method default void print() { System.out.println('TestInterface :: Default method'); } } class TestClass implements TestInterface { // override cubeNumber method public void cubeNumber(int num) { System.out.println('Cube of given number ' + num+ ':' + num*num*num); } } class Main{ public static void main(String args()) { TestClass obj = new TestClass(); obj.cubeNumber(5); // call default method print using class object obj.print(); } }
Production:
Questions et réponses basées sur des scénarios SQL
Le programme Java ci-dessus illustre la méthode par défaut dans l'interface. Dans la méthode main, notez que nous pouvons appeler la méthode par défaut de l'interface en utilisant l'objet de classe. En effet, lorsque la classe implémente l'interface, la méthode par défaut est également disponible pour la classe.
Noter: Nous aurions pu remplacer la méthode print () également dans la classe d'implémentation. Notez qu'en cas de substitution, le modificateur d'accès de la méthode par défaut deviendra public dans la classe d'implémentation.
Méthodes par défaut et héritage multiple
Il pourrait se produire une situation dans le cas d'interfaces multiples où chaque interface pourrait avoir une méthode par défaut avec le même prototype. Dans un tel cas, le compilateur ne sait pas quelle méthode appeler.
comment ouvrir un fichier jar sous windows 10
Lorsque cette situation se produit dans laquelle la méthode par défaut a le même prototype dans toutes les interfaces, alors la solution est de remplacer la méthode dans la classe d'implémentation de sorte que lorsque l'objet de classe d'implémentation appelle la méthode par défaut, le compilateur appelle la méthode implémentée dans la classe .
Le programme Java suivant illustre l'utilisation de la méthode par défaut avec plusieurs interfaces.
//Interface_One interface Interface_One{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_One::defaultMethod'); } } //Interface_Two interface Interface_Two{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_Two::defaultMethod'); } } class TestExample implements Interface_One, Interface_Two{ public void disp(String str){ System.out.println('String is: '+str); } //override defaultMethod to take care of the ambiguity public void defaultMethod(){ System.out.println('TestExample::defaultMethod'); } } class Main{ public static void main(String() args) { TestExample obj = new TestExample(); //call the default method obj.defaultMethod(); } }
Production:
Dans le programme ci-dessus, nous avons remplacé la méthode par défaut (qui a le même prototype dans les deux interfaces) dans la classe d'implémentation. De cette façon, lorsque nous appelons la méthode par défaut à partir de la méthode main en utilisant l'objet de la classe d'implémentation, la méthode surchargée est appelée.
Interfaces fonctionnelles Java 8
Une interface fonctionnelle est une interface qui n'a qu'une seule méthode abstraite. Il peut contenir n'importe quel nombre de méthodes par défaut et statiques, mais la méthode abstraite qu'il contient en est exactement une. De plus, une interface fonctionnelle peut avoir des déclarations de méthodes de classe d'objets.
L'interface fonctionnelle est appelée « Interface de méthode abstraite unique ' ou ' Interface SAM ». L'interface SAM est une nouvelle fonctionnalité de Java.
Dans un programme Java, la présence d'une interface fonctionnelle est indiquée à l'aide d'un @Interface fonctionnelle annotation. Lorsque le compilateur rencontre cette annotation, il sait que l'interface qui suit cette annotation est fonctionnelle. Par conséquent, s'il contient plus d'une méthode abstraite, il clignote une erreur.
L'annotation @Interface fonctionnelle cependant, n'est pas obligatoire en Java.
Le programme suivant illustre l'interface fonctionnelle en Java:
//declare a functional interface @FunctionalInterface //annotation indicates it’s a functional interface interface function_Interface{ void disp_msg(String msg); // abstract method // Object class methods. int hashCode(); String toString(); boolean equals(Object obj); } //implementation of Functional Interface class FunctionalInterfaceExample implements function_Interface{ public void disp_msg(String msg){ System.out.println(msg); } } class Main{ public static void main(String() args) { //create object of implementation class and call method FunctionalInterfaceExample finte = new FunctionalInterfaceExample(); finte.disp_msg('Hello, World!!!'); } }
Production:
L'interface fonctionnelle dans le programme ci-dessus a une seule méthode abstraite et a également une déclaration de méthode de classe d'objet comme hashCode, toString et equals. Dans la classe qui implémente cette interface, la méthode abstraite est remplacée. Dans la méthode principale, nous créons un objet de classe d'implémentation et utilisons la méthode.
Les interfaces telles que Runnable et Comparable sont des exemples d'interfaces fonctionnelles fournies en Java. Java 8 nous permet d'attribuer des expressions lambda à l'objet d'interface fonctionnelle.
L'exemple de programme suivant illustre cela.
class Main{ public static void main(String args()) { // use lambda expression to create the object new Thread(()-> {System.out.println('New thread created with functional interface');}).start(); } }
Production:
Java 8 fournit également de nombreuses interfaces fonctionnelles intégrées dans le package java.util.function.
Ces interfaces intégrées sont décrites ci-dessous:
# 1) Prédicat
Il s'agit d'une interface fonctionnelle en Java qui a un seul test de méthode abstraite. La méthode «test» renvoie la valeur booléenne après avoir testé l’argument spécifié.
Vous trouverez ci-dessous le prototype de la méthode de test de l'interface Predicate.
public interface Predicate { public boolean test(T t); }
# 2) Opérateur binaire
L'interface BinaryOperator fournit une méthode abstraite «apply» qui accepte deux arguments et renvoie une valeur résultante du même type que les arguments.
Le prototype de la méthode accept est:
public interface BinaryOperator { public T apply (T x, T y); }
# 3) Fonction
L’interface Function est une interface fonctionnelle qui possède également une méthode abstraite nommée «apply». Cette méthode apply, cependant, prend un seul argument de type T et renvoie une valeur de type R.
Le prototype de la méthode apply est le suivant:
public interface Function { public R apply(T t); }
Le programme Java suivant illustre le prédicat d'interface fonctionnelle intégré ci-dessus.
import java.util.*; import java.util.function.Predicate; class Main { public static void main(String args()) { // create a list of strings List names = Arrays.asList('Karen','Mia','Sydney','Lacey','Megan'); // declare string type predicate and use lambda expression to create object Predicate p = (s)->s.startsWith('M'); System.out.println('Names starting with M:'); // Iterate through the list for (String st:names) { // test each entry with predicate if (p.test(st)) System.out.println(st); } } }
Production:
Comme nous pouvons le voir dans le programme ci-dessus, nous avons une liste de chaînes. En utilisant l'interface fonctionnelle Predicate, nous testons si l'élément dans la chaîne commence par M et si c'est le cas, il imprime le nom.
Interface de classe Vs en Java
Bien que la classe et l'interface soient similaires car elles ont une syntaxe similaire, ces deux entités présentent plus de différences que de similitudes.
Voyons quelques-unes des différences entre la classe et l'interface en Java.
Classer | Interface |
---|---|
Nous pouvons instancier et créer des objets à partir d'une classe. | Une interface ne peut pas être instanciée. |
Le mot-clé «classe» est utilisé pour créer une classe. | L’interface est créée à l’aide du mot-clé «interface». |
Les classes ne prennent pas en charge l'héritage multiple en Java. | Les interfaces prennent en charge l'héritage multiple en Java. |
La classe contient les constructeurs. | Les interfaces ne contiennent pas de constructeurs. |
La classe ne peut pas contenir de méthodes abstraites. | Les interfaces ne contiennent que des méthodes abstraites. |
La classe peut avoir des variables et des méthodes par défaut, publiques, privées ou protégées. | L'interface n'a que des variables et des méthodes publiques par défaut. |
Il n'est pas obligatoire d'associer des modificateurs de non-accès aux variables de la classe. | Les interfaces peuvent avoir des variables statiques ou définitives. |
Nous pouvons hériter d'une autre classe d'une classe. | Nous ne pouvons pas hériter d'une classe de l'interface. |
La classe peut être héritée à l’aide du mot-clé «extend». | L’interface peut être implémentée par une autre classe à l’aide du mot-clé ‘implements’. Il peut être hérité par une autre interface à l’aide du mot-clé «extend». |
Java étend ses implémentations
«Étend» | 'met en oeuvre' |
---|---|
Les interfaces ne prennent en charge que les modificateurs statiques et finaux sans accès. | Abstract prend en charge tous les modificateurs sans accès comme statique, final, non statique et non final. |
Une classe utilise le mot-clé 'extend' pour hériter d'une autre classe. | Le mot clé 'implements' est utilisé par une classe pour implémenter une interface. |
Une classe héritant d'une autre classe peut ou non remplacer toutes les méthodes de la classe parent. | La classe implémentant l'interface doit remplacer toutes les méthodes abstraites de l'interface. |
Nous ne pouvons étendre qu'une seule classe à la fois en utilisant le mot clé extend. | Nous pouvons implémenter plusieurs interfaces en utilisant le mot clé 'implements'. |
Une interface peut étendre une autre interface à l’aide du mot-clé «extend». | Une interface ne peut pas implémenter une autre interface en utilisant des mots clés 'implements'. |
La classe abstraite peut implémenter l'interface en Java
Oui, une classe abstraite peut implémenter une interface à l’aide du mot-clé ‘implements’. La classe abstraite n'a pas besoin d'implémenter toutes les méthodes abstraites d'interface. Mais dans l'ensemble, c'est une bonne pratique de conception d'avoir une interface avec toutes les méthodes abstraites, puis une classe abstraite implémentant cette interface, puis les classes concrètes.
Vous trouverez ci-dessous un exemple d'une telle implémentation en Java.
Ici java.util.List est une interface. Cette interface est implémentée par java.util.AbstractList. Ensuite, cette classe AbstractList est étendue par deux classes concrètes, à savoir LinkedList et ArrayList.
Si les classes LinkedList et ArrayList avaient implémenté directement l'interface List, elles devraient implémenter toutes les méthodes abstraites de l'interface List.
Mais dans ce cas, la classe AbstractList implémente les méthodes de l'interface List et les transmet à LinkedList et ArrayList. Nous avons donc ici l'avantage de déclarer le type à partir de l'interface et la flexibilité de classe abstraite de l'implémentation du comportement commun.
Quand utiliser une classe abstraite et une interface en Java
Nous utilisons principalement une classe abstraite pour définir un comportement par défaut ou commun des classes enfants qui s'étendent à partir de cette classe abstraite. Une interface permet de définir un contrat entre deux systèmes qui interagissent dans une application.
Certaines situations spécifiques sont idéales pour les interfaces à utiliser et certains problèmes qui ne peuvent être résolus qu'en utilisant des classes abstraites. Dans cette section, nous discuterons quand nous pouvons utiliser l'interface et quand nous pouvons utiliser des classes abstraites.
Quand utiliser une interface:
- Les interfaces sont principalement utilisées lorsque nous avons une petite fonctionnalité concise à implémenter.
- Lorsque nous implémentons des API et que nous savons qu'elles ne changeront pas avant un certain temps, nous optons alors pour les interfaces.
- Les interfaces nous permettent d'implémenter l'héritage multiple. Par conséquent, lorsque nous devons implémenter l'héritage multiple dans notre application, nous optons pour les interfaces.
- Lorsque nous avons une large gamme d'objets, encore une fois, les interfaces sont un meilleur choix.
- De même, lorsque nous devons fournir une fonctionnalité commune à de nombreuses classes non liées, des interfaces sont toujours utilisées.
Quand utiliser une classe abstraite:
- Les classes abstraites sont principalement utilisées lorsque nous avons besoin d'utiliser l'héritage dans notre application.
- Comme les interfaces traitent des méthodes et des variables publiques, chaque fois que nous voulons utiliser des modificateurs d'accès non publics dans notre programme, nous utilisons des classes abstraites.
- Si de nouvelles méthodes doivent être ajoutées, il vaut mieux le faire dans une classe abstraite que dans l'interface. Parce que si nous ajoutons une nouvelle méthode dans l'interface, l'ensemble de l'implémentation change car les interfaces n'ont que des prototypes de méthode et l'implémentation de classe à l'aide de l'interface fournira l'implémentation.
- Si nous voulons différentes versions des composants en cours de développement, nous optons pour une classe abstraite. Nous pouvons changer les classes abstraites plus facilement. Mais les interfaces ne peuvent pas être modifiées. Si nous voulons une nouvelle version, nous devons réécrire l'intégralité de l'interface.
- Lorsque nous voulons fournir une implémentation commune pour tous les composants, la classe abstraite est le meilleur choix.
Interface vs classe abstraite en Java
Vous trouverez ci-dessous quelques-unes des différences entre les interfaces et les classes abstraites en Java.
Interface | Classe abstraite |
---|---|
Une interface est déclarée à l’aide du mot-clé ‘interface’. | Une classe abstraite est déclarée à l’aide du mot-clé ‘abstract’. |
L’interface peut être implémentée à l’aide du mot-clé ‘implements’. | Le résumé peut être hérité à l’aide du mot-clé «extend». |
Une interface ne peut pas étendre une classe ou implémenter une interface, elle ne peut étendre qu'une autre interface. | Une classe abstraite peut étendre une classe ou implémenter plusieurs interfaces. |
Les membres de l'interface ne peuvent être que publics. | Les membres de la classe abstraite peuvent être publics, privés ou protégés. |
Une interface ne peut pas être utilisée pour fournir une implémentation. Il ne peut être utilisé que comme déclaration. | Une classe abstraite peut être utilisée pour implémenter l'interface. |
L'héritage multiple peut être obtenu à l'aide d'interfaces. | La classe abstraite ne prend pas en charge l'héritage multiple. |
Les interfaces ne peuvent avoir que des méthodes abstraites. Depuis Java 8, il peut avoir des méthodes statiques et par défaut. | Une classe abstraite peut avoir une méthode abstraite ou non abstraite. |
Enum Héritage en Java
Nous avons discuté des types de données enum dans notre discussion sur les types de données en Java. Toutes les énumérations s'étendent de la classe java.lang.Enum. Cette classe java.lang.Enum est une classe abstraite.
De plus, toutes les classes enum en Java sont «finales» par défaut. Par conséquent, une tentative d'hériter d'une classe à partir de n'importe quelle classe d'énumération entraîne une erreur du compilateur.
Comme Java n'autorise pas l'héritage multiple, nous ne pouvons pas hériter de la classe enum d'une autre classe car la classe enum hérite déjà de java.lang.Enum. Cependant, les classes enum peuvent implémenter des interfaces en Java et cela s'appelle l'héritage Enum en Java.
Vous trouverez ci-dessous un exemple d'héritage Enum en Java.
//WeekDays interface declaration interface WeekDays { public void displaydays(); } //enum class implementing WeekDays interface enum Days implements WeekDays { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,FRIDAY, SATURDAY; public void displaydays() { //Override displaydays method System.out.println('The day of the week: ' + this); } } class Main { public static void main(String() args) { Days.MONDAY.displaydays(); //access enum value } }
Production:
Ici, nous avons une interface WeekDays avec un prototype de méthode abstraite displaydays (). Ensuite, nous définissons une classe d'énumération Days qui implémente l'interface WeekDays. Ici, nous définissons les valeurs d'énumération de SUNDAY à SATURDAY et remplaçons également la méthode displaydays.
Enfin, dans la méthode main, nous accédons à la valeur d'énumération et l'afficherons.
Questions fréquemment posées
Q # 1) Que se passe-t-il si vous donnez un corps de méthode dans l'interface?
Répondre: Pour les versions Java antérieures à Java 8, le corps de la méthode n'est pas autorisé dans l'interface. Mais depuis Java 8, nous pouvons définir une méthode par défaut ou statique à l'intérieur de l'interface.
Q # 2) Une interface peut-elle avoir des variables dans Java 8?
Répondre: Nous pouvons avoir des variables constantes dans Java 8 en utilisant des modificateurs statiques et finaux. Mais nous ne pouvons pas avoir de variables d'instance dans les interfaces Java. Toute tentative de déclaration de variables d'instance dans une interface entraînera une erreur du compilateur.
Q # 3) Quelles sont les améliorations des interfaces dans Java 8?
Répondre: L'amélioration la plus importante pour les interfaces dans Java 8 est que les méthodes statiques et par défaut sont autorisées dans les interfaces. Nous pouvons avoir des méthodes déclarées comme statiques ou par défaut et les définir dans l'interface.
Q # 4) Pouvons-nous remplacer la méthode par défaut dans l'interface Java?
Répondre: Non. Il n'est pas obligatoire de remplacer la méthode par défaut dans l'interface. En effet, lorsque nous implémentons une interface dans une classe, la méthode par défaut de la classe est accessible à la classe d'implémentation. Par conséquent, en utilisant l'objet de la classe d'implémentation, nous pouvons accéder à la méthode par défaut de l'interface.
Q # 5) Les interfaces peuvent-elles avoir des champs en Java?
questions d'entrevue sur les services Web reposants java
Répondre: Oui, nous pouvons avoir des champs ou des variables dans les interfaces en Java mais par défaut, tous ces champs sont statiques, finaux et publics.
Conclusion
Dans ce didacticiel, nous avons discuté des modifications apportées aux interfaces dans Java 8. Java 8 a introduit des méthodes statiques et par défaut dans les interfaces. Auparavant, nous ne pouvions avoir que des méthodes abstraites dans l'interface. Mais à partir de Java 8, nous pouvons définir des méthodes par défaut et statiques en Java.
De plus, Java 8 permet l'utilisation d'expressions lambda avec les interfaces fonctionnelles en Java. Ensuite, nous avons également discuté des classes abstraites et des interfaces et vu quand utiliser chacune d'elles en Java. Nous avons également vu l'héritage enum en Java.
Nous avons également discuté de certaines des différences entre les extensions et les implémentations, la classe et l'interface, la classe abstraite et l'interface, etc.
=> Consultez TOUS les didacticiels Java ici.
lecture recommandée
- Tutoriel sur l'interface Java et la classe abstraite avec des exemples
- Interfaces comparables et comparatives en Java
- Interface ListIterator en Java avec des exemples
- Définir l'interface en Java: didacticiel sur le jeu Java avec des exemples
- Interface de marqueur en Java: sérialisable et clonable
- Méthode Java String length () avec exemples
- Déploiement Java: création et exécution d'un fichier JAR Java
- Comment utiliser la méthode Java toString?