Menu
Coddy logo textTech

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 ne pouvaient contenir que des méthodes abstraites sans implémentation. À partir de Java 8, les interfaces ont acquis la capacité 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 en utilisant le 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 implémentant Drawable obtient la méthode display() gratuitement. Ceci est particulièrement utile pour ajouter de nouvelles méthodes à des interfaces existantes sans casser 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 en utilisant le 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 d'interface statiques ne peuvent pas être redéfinies et ne sont pas héritées par les classes d'implémentation. Elles sont utiles pour les méthodes utilitaires liées à l'objectif de l'interface.

Si une classe implémente deux interfaces avec la même signature de méthode par défaut, la classe doit redéfinir cette méthode pour résoudre le conflit.

challenge icon

Défi

Facile

Construisons un système de messagerie qui met en avant à la fois les méthodes par défaut (default) et statiques dans les interfaces. Vous allez créer une interface avec des fonctionnalités intégrées que les classes d'implémentation peuvent utiliser directement ou personnaliser selon leurs besoins.

Vous organiserez votre code sur quatre fichiers :

  • Messenger.java : Définissez une interface qui représente n'importe quel service de messagerie. Elle doit déclarer une méthode abstraite sendMessage(String message) qui ne retourne rien (void). Ajoutez une méthode par défaut appelée sendWithTimestamp(String message) qui affiche : [TIMESTAMP] suivi de l'appel à sendMessage(message). Incluez également une méthode statique appelée formatMessage(String message) qui retourne le message converti en majuscules.
  • EmailMessenger.java : Créez une classe qui implémente Messenger. Elle possède un champ recipient (String). Incluez un constructeur pour initialiser le destinataire. Implémentez sendMessage() pour afficher : Email to [recipient]: [message]. Cette classe utilise la méthode par défaut sendWithTimestamp() telle quelle.
  • SMSMessenger.java : Créez une autre classe qui implémente Messenger. Elle possède un champ phoneNumber (String). Incluez un constructeur pour initialiser le numéro de téléphone. Implémentez sendMessage() pour afficher : SMS to [phoneNumber]: [message]. Surchargez la méthode par défaut sendWithTimestamp() pour afficher : [URGENT] suivi de l'appel à sendMessage(message) au lieu d'utiliser le comportement d'horodatage par défaut.
  • Main.java : Rassemblez tout pour démontrer les méthodes d'interface par défaut et statiques. Vous recevrez trois entrées : un destinataire d'e-mail, un numéro de téléphone et un message. Tout d'abord, utilisez la méthode statique Messenger.formatMessage() pour formater le message et le stocker. Ensuite, créez un EmailMessenger et un SMSMessenger. Pour chaque messager, appelez sendWithTimestamp() avec le message formaté — remarquez comment l'EmailMessenger utilise l'implémentation par défaut tandis que le SMSMessenger utilise sa version surchargée.

Vous recevrez trois entrées : le destinataire de l'e-mail (String), le numéro de téléphone (String) et le message (String).

Votre sortie devrait afficher quatre lignes au total — deux pour chaque messager. L'EmailMessenger affichera le préfixe d'horodatage par défaut, tandis que le SMSMessenger affichera son préfixe urgent personnalisé. Les deux utiliseront le message formaté statiquement (en majuscules) !

Aide-mémoire

À partir de Java 8, les interfaces peuvent inclure des méthodes par défaut et des méthodes statiques en plus des méthodes abstraites.

Les méthodes par défaut fournissent une implémentation directement dans l'interface en utilisant le mot-clé default. Les classes qui implémentent l'interface héritent automatiquement de ce comportement mais peuvent le surcharger si nécessaire :

public interface Drawable {
    void draw();
    
    default void display() {
        System.out.println("Displaying on screen...");
        draw();
    }
}

Les méthodes statiques dans les interfaces appartiennent à l'interface elle-même et sont appelées en utilisant le nom de l'interface. Elles ne peuvent pas être surchargées et ne sont pas héritées par les classes d'implémentation :

public interface MathOperations {
    static int add(int a, int b) {
        return a + b;
    }
}

// Utilisation
int result = MathOperations.add(5, 3);

Si une classe implémente deux interfaces avec la même signature de méthode par défaut, la classe doit surcharger cette méthode pour résoudre le conflit.

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 le EmailMessenger avec le message formaté
        
        // TODO: Appeler sendWithTimestamp() sur le SMSMessenger avec le message formaté
    }
}
quiz iconTestez-vous

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