Menu
Coddy logo textTech

Default- & statische Methoden in Interfaces

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 37 von 87.

Ursprünglich konnten Interfaces nur abstrakte Methoden ohne Implementierung enthalten. Seit Java 8 haben Interfaces die Möglichkeit erhalten, Default-Methoden und statische Methoden aufzunehmen, was sie flexibler macht.

Eine Default-Methode stellt eine Implementierung direkt im Interface unter Verwendung des Schlüsselworts default bereit. Klassen, die das Interface implementieren, erben dieses Verhalten automatisch, können es jedoch bei Bedarf überschreiben:

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

Jede Klasse, die Drawable implementiert, erhält die display()-Methode kostenlos. Dies ist besonders nützlich, um bestehenden Schnittstellen neue Methoden hinzuzufügen, ohne Klassen zu beeinträchtigen, die diese bereits implementieren.

Statische Methoden in Interfaces funktionieren wie statische Methoden in Klassen. Sie gehören zum Interface selbst und werden über den Namen des Interfaces aufgerufen:

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

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

Statische Interface-Methoden können nicht überschrieben werden und werden nicht von implementierenden Klassen geerbt. Sie sind nützlich für Utility-Methoden, die mit dem Zweck des Interfaces in Verbindung stehen.

Wenn eine Klasse zwei Interfaces mit der gleichen Default-Methoden-Signatur implementiert, muss die Klasse diese Methode überschreiben, um den Konflikt zu lösen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Nachrichtensystem erstellen, das sowohl Standard- (default) als auch statische Methoden in Schnittstellen (Interfaces) demonstriert. Sie werden ein Interface mit integrierter Funktionalität erstellen, die implementierende Klassen direkt verwenden oder bei Bedarf anpassen können.

Sie werden Ihren Code über vier Dateien organisieren:

  • Messenger.java: Definieren Sie ein Interface, das einen beliebigen Nachrichtendienst repräsentiert. Es sollte eine abstrakte Methode sendMessage(String message) deklarieren, die void zurückgibt. Fügen Sie eine default method namens sendWithTimestamp(String message) hinzu, die Folgendes ausgibt: [TIMESTAMP] gefolgt vom Aufruf von sendMessage(message). Fügen Sie außerdem eine static method namens formatMessage(String message) hinzu, die die Nachricht in Großbuchstaben umgewandelt zurückgibt.
  • EmailMessenger.java: Erstellen Sie eine Klasse, die Messenger implementiert. Sie hat ein Feld recipient (String). Fügen Sie einen Konstruktor hinzu, um den Empfänger zu initialisieren. Implementieren Sie sendMessage(), um Folgendes auszugeben: Email to [recipient]: [message]. Diese Klasse verwendet die standardmäßige sendWithTimestamp()-Methode unverändert.
  • SMSMessenger.java: Erstellen Sie eine weitere Klasse, die Messenger implementiert. Sie hat ein Feld phoneNumber (String). Fügen Sie einen Konstruktor hinzu, um die Telefonnummer zu initialisieren. Implementieren Sie sendMessage(), um Folgendes auszugeben: SMS to [phoneNumber]: [message]. Überschreiben Sie die standardmäßige sendWithTimestamp()-Methode, um Folgendes auszugeben: [URGENT] gefolgt vom Aufruf von sendMessage(message), anstatt das Standard-Zeitstempel-Verhalten zu verwenden.
  • Main.java: Bringen Sie alles zusammen, um sowohl Standard- als auch statische Interface-Methoden zu demonstrieren. Sie erhalten drei Eingaben: einen E-Mail-Empfänger, eine Telefonnummer und eine Nachricht. Verwenden Sie zuerst die statische Methode Messenger.formatMessage(), um die Nachricht zu formatieren und zu speichern. Erstellen Sie dann einen EmailMessenger und einen SMSMessenger. Rufen Sie für jeden Messenger sendWithTimestamp() mit der formatierten Nachricht auf – beachten Sie, wie der EmailMessenger die Standardimplementierung verwendet, während der SMSMessenger seine überschriebene Version nutzt.

Sie erhalten drei Eingaben: den E-Mail-Empfänger (String), die Telefonnummer (String) und die Nachricht (String).

Ihre Ausgabe sollte insgesamt vier Zeilen zeigen – zwei für jeden Messenger. Der EmailMessenger zeigt das Standard-Zeitstempel-Präfix, während der SMSMessenger sein benutzerdefiniertes Dringlichkeits-Präfix zeigt. Beide verwenden die statisch formatierte (großgeschriebene) Nachricht!

Spickzettel

Ab Java 8 können Schnittstellen zusätzlich zu abstrakten Methoden auch Default-Methoden und statische Methoden enthalten.

Default-Methoden stellen eine Implementierung direkt in der Schnittstelle unter Verwendung des Schlüsselworts default bereit. Klassen, die die Schnittstelle implementieren, erben dieses Verhalten automatisch, können es jedoch bei Bedarf überschreiben:

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

Statische Methoden in Schnittstellen gehören zur Schnittstelle selbst und werden über den Schnittstellennamen aufgerufen. Sie können nicht überschrieben werden und werden nicht von implementierenden Klassen geerbt:

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

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

Wenn eine Klasse zwei Schnittstellen mit derselben Signatur für eine Default-Methode implementiert, muss die Klasse diese Methode überschreiben, um den Konflikt zu lösen.

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String emailRecipient = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String message = scanner.nextLine();
        
        // TODO: Verwende Messenger.formatMessage(), um die Nachricht zu formatieren und zu speichern
        
        // TODO: Erstelle einen EmailMessenger mit dem email recipient
        
        // TODO: Erstelle einen SMSMessenger mit der phoneNumber
        
        // TODO: Rufe sendWithTimestamp() auf dem EmailMessenger mit der formatierten Nachricht auf
        
        // TODO: Rufe sendWithTimestamp() auf dem SMSMessenger mit der formatierten Nachricht auf
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung