Default et Static dans les Interfaces
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 37 sur 87.
À l’origine, les interfaces pouvaient uniquement contenir des méthodes abstraites sans implémentation. À partir de Java 8, les interfaces ont acquis la possibilité d’inclure des méthodes par défaut et des méthodes statiques, ce qui les rend plus flexibles.
Une méthode par défaut fournit une implémentation directement dans l’interface à l’aide du mot-clé default. Les classes qui implémentent l’interface héritent automatiquement de ce comportement, mais peuvent le redéfinir si nécessaire :
public interface Drawable {
void draw();
default void display() {
System.out.println("Displaying on screen...");
draw();
}
}Toute classe qui implémente Drawable obtient gratuitement la méthode display(). Cela est particulièrement utile pour ajouter de nouvelles méthodes aux interfaces existantes sans interrompre les classes qui les implémentent déjà.
Les méthodes statiques dans les interfaces fonctionnent comme les méthodes statiques dans les classes. Elles appartiennent à l’interface elle-même et sont appelées à l’aide du nom de l’interface :
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// Utilisation
int result = MathOperations.add(5, 3);Les méthodes statiques d’une interface ne peuvent pas être redéfinies et ne sont pas héritées par les classes qui l’implémentent. Elles sont utiles pour les méthodes utilitaires liées à la fonction de l’interface.
Si une classe implémente deux interfaces possédant la même signature de méthode par défaut, la classe doit redéfinir cette méthode afin de résoudre le conflit.
Défi
FacileConstruisons un système de messagerie qui présente à la fois les méthodes par défaut et les méthodes statiques dans les interfaces. Tu vas créer une interface dotée de fonctionnalités intégrées que les classes qui l’implémentent peuvent utiliser directement ou personnaliser selon leurs besoins.
Tu organiseras ton code sur quatre fichiers :
Messenger.java: définis une interface qui représente tout service de messagerie. Elle doit déclarer une méthode abstraitesendMessage(String message)qui renvoie void. Ajoute une méthode par défaut appeléesendWithTimestamp(String message)qui affiche :[TIMESTAMP], puis appellesendMessage(message). Inclus également une méthode statique appeléeformatMessage(String message)qui renvoie le message converti en majuscules.EmailMessenger.java: crée une classe qui implémenteMessenger. Elle possède un champrecipient(String). Inclus un constructeur pour initialiser le destinataire. ImplémentesendMessage()afin d’afficher :Email to [recipient]: [message]. Cette classe utilise telle quelle la méthode par défautsendWithTimestamp().SMSMessenger.java: crée une autre classe qui implémenteMessenger. Elle possède un champphoneNumber(String). Inclus un constructeur pour initialiser le numéro de téléphone. ImplémentesendMessage()afin d’afficher :SMS to [phoneNumber]: [message]. Redéfinis la méthode par défautsendWithTimestamp()pour afficher :[URGENT], puis appelersendMessage(message)au lieu d’utiliser le comportement par défaut avec horodatage.Main.java: rassemble tout afin de démontrer les méthodes d’interface par défaut et statiques. Tu recevras trois entrées : un destinataire e-mail, un numéro de téléphone et un message. Commence par utiliser la méthode statiqueMessenger.formatMessage()pour formater le message et le stocker. Crée ensuite un EmailMessenger et un SMSMessenger. Pour chaque service de messagerie, appellesendWithTimestamp()avec le message formaté : remarque comment EmailMessenger utilise l’implémentation par défaut, tandis que SMSMessenger utilise sa version redéfinie.
Tu recevras trois entrées : le destinataire e-mail (String), le numéro de téléphone (String) et le message (String).
Ta sortie doit afficher quatre lignes au total : deux pour chaque service de messagerie : une ligne de préfixe ([TIMESTAMP] ou [URGENT]), suivie de la ligne du message. EmailMessenger affichera le préfixe d’horodatage par défaut, tandis que SMSMessenger affichera son préfixe urgent personnalisé. Tous deux utiliseront le message formaté statiquement (en majuscules) !
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
String emailRecipient = scanner.nextLine();
String phoneNumber = scanner.nextLine();
String message = scanner.nextLine();
// TODO: Utiliser Messenger.formatMessage() pour formater le message et le stocker
// TODO: Créer un EmailMessenger avec le destinataire de l'e-mail
// TODO: Créer un SMSMessenger avec le numéro de téléphone
// TODO: Appeler sendWithTimestamp() sur l'EmailMessenger avec le message formaté
// TODO: Appeler sendWithTimestamp() sur le SMSMessenger avec le message formaté
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron ItérateurEntraînez-vous par vous-même : Compilateur Java en ligne