Default & Static in Interfaces
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 37 von 87.
Ursprünglich konnten Schnittstellen nur abstrakte Methoden ohne Implementierung enthalten. Ab Java 8 erhielten Schnittstellen die Möglichkeit, Default-Methoden und statische Methoden einzuschließen, wodurch sie flexibler wurden.
Eine Standardmethode stellt mithilfe des Schlüsselworts default direkt in der Schnittstelle eine Implementierung bereit. Klassen, die die Schnittstelle implementieren, erben dieses Verhalten automatisch, können es aber 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 Methode display() 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 Schnittstellen funktionieren wie statische Methoden in Klassen. Sie gehören zur Schnittstelle selbst und werden mithilfe des Schnittstellennamens aufgerufen:
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// Verwendung
int result = MathOperations.add(5, 3);Statische Schnittstellenmethoden können nicht überschrieben werden und werden nicht von implementierenden Klassen geerbt. Sie sind nützlich für utility-Methoden, die mit dem Zweck der Schnittstelle zusammenhängen.
Wenn eine Klasse zwei Schnittstellen mit derselben Signatur einer Standardmethode implementiert, muss die Klasse diese Methode überschreiben, um den Konflikt zu lösen.
Aufgabe
EinfachErstellen wir ein Nachrichtensystem, das sowohl Standard- als auch statische Methoden in Interfaces demonstriert. Du erstellst ein Interface mit integrierter Funktionalität, die implementierende Klassen direkt verwenden oder nach Bedarf anpassen können.
Du organisierst deinen Code auf vier Dateien:
Messenger.java: Definiere ein Interface, das jeden Nachrichtendienst repräsentiert. Es soll eine abstrakte MethodesendMessage(String message)deklarieren, die void zurückgibt. Füge eine default-Methode namenssendWithTimestamp(String message)hinzu, die Folgendes ausgibt:[TIMESTAMP], gefolgt vom Aufruf vonsendMessage(message). Füge außerdem eine statische Methode namensformatMessage(String message)hinzu, die die Nachricht in Großbuchstaben umgewandelt zurückgibt.EmailMessenger.java: Erstelle eine Klasse, dieMessengerimplementiert. Sie besitzt ein Feldrecipient(String). Füge einen Konstruktor hinzu, der den Empfänger initialisiert. ImplementieresendMessage(), sodass Folgendes ausgegeben wird:Email to [recipient]: [message]. Diese Klasse verwendet die standardmäßigesendWithTimestamp()-Methode unverändert.SMSMessenger.java: Erstelle eine weitere Klasse, dieMessengerimplementiert. Sie besitzt ein FeldphoneNumber(String). Füge einen Konstruktor hinzu, der die Telefonnummer initialisiert. ImplementieresendMessage(), sodass Folgendes ausgegeben wird:SMS to [phoneNumber]: [message]. Überschreibe die standardmäßigesendWithTimestamp()-Methode, sodass[URGENT]ausgegeben wird, gefolgt vom Aufruf vonsendMessage(message), anstatt das standardmäßige Zeitstempelverhalten zu verwenden.Main.java: Führe alles zusammen, um sowohl standardmäßige als auch statische Interface-Methoden zu demonstrieren. Du erhältst drei Eingaben: einen E-Mail-Empfänger, eine Telefonnummer und eine Nachricht. Verwende zuerst die statische MethodeMessenger.formatMessage(), um die Nachricht zu formatieren und zu speichern. Erstelle dann einen EmailMessenger und einen SMSMessenger. Rufe für jeden MessengersendWithTimestamp()mit der formatierten Nachricht auf: Beachte, wie EmailMessenger die Standardimplementierung verwendet, während SMSMessenger seine überschriebene Version verwendet.
Du erhältst drei Eingaben: den E-Mail-Empfänger (String), die Telefonnummer (String) und die Nachricht (String).
Deine Ausgabe sollte insgesamt vier Zeilen enthalten: zwei für jeden Messenger: eine Präfixzeile ([TIMESTAMP] oder [URGENT]), gefolgt von der Nachrichtenzeile. EmailMessenger zeigt das standardmäßige Zeitstempelpräfix an, während SMSMessenger sein benutzerdefiniertes Dringlichkeitspräfix anzeigt. Beide verwenden die statisch formatierte Nachricht (in Großbuchstaben)!
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 speichere sie
// TODO: Erstelle einen EmailMessenger mit dem E-Mail-Empfänger
// TODO: Erstelle einen SMSMessenger mit der Telefonnummer
// TODO: Rufe sendWithTimestamp() auf dem EmailMessenger mit der formatierten Nachricht auf
// TODO: Rufe sendWithTimestamp() auf dem SMSMessenger mit der formatierten Nachricht auf
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler