Interfaces implementieren
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 35 von 87.
Um eine Schnittstelle zu verwenden, muss eine Klasse sie mithilfe des Schlüsselworts implements implementieren. Die Klasse stellt dann konkrete Implementierungen für alle in der Schnittstelle deklarierten Methoden bereit:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}Wenn eine Klasse ein Interface implementiert, aber keine Implementierungen für alle seine Methoden bereitstellt, gibt der Compiler einen Fehler aus. Die Annotation @Override ist optional, wird aber empfohlen, da sie dabei hilft, Fehler zu erkennen.
Wie bei abstrakten Klassen kannst du ein Interface als Referenztyp verwenden. Dies ermöglicht Polymorphismus, bei dem verschiedene Klassen, die dasselbe Interface implementieren, einheitlich behandelt werden können:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Zeichne einen Kreis mit Radius 5.0
shape2.draw(); // Zeichne ein Rechteck 4.0 x 3.0Das ist leistungsstark, weil Code, der mit Drawable-Referenzen arbeitet, den spezifischen Klassentyp nicht kennen muss. Er muss nur wissen, dass das Objekt gezeichnet werden kann.
In der nächsten Lektion siehst du, wie eine einzelne Klasse mehrere Schnittstellen gleichzeitig implementieren kann.
Aufgabe
EinfachErstellen wir ein Lautsprechersystem, das zeigt, wie Klassen Schnittstellen implementieren. Du erstellst eine Schnittstelle, die definiert, was jeder Lautsprecher tun kann, und baust anschließend zwei verschiedene Lautsprechertypen, die diesen Vertrag jeweils auf ihre eigene Weise implementieren.
Du organisierst deinen Code auf vier Dateien verteilt:
Speaker.java: Definiere eine Schnittstelle namensSpeaker, die festlegt, was jeder Lautsprecher können muss. Jeder Lautsprecher sollte über einespeak()-Methode verfügen, die einen String zurückgibt. Dies ist der Vertrag, den alle implementierenden Klassen erfüllen müssen.Human.java: Erstelle eine Klasse, die die SchnittstelleSpeakerimplementiert. Ein Human verfügt über einname-Feld (String). Füge einen Konstruktor zur Initialisierung des Namens hinzu und implementiere diespeak()-Methode so, dass sie Folgendes zurückgibt:[name] says: Hello everyone!Robot.java: Erstelle eine weitere Klasse, die die SchnittstelleSpeakerimplementiert. Ein Robot verfügt über einmodel-Feld (String). Füge einen Konstruktor zur Initialisierung des Modells hinzu und implementiere diespeak()-Methode so, dass sie Folgendes zurückgibt:Robot [model] says: Beep boop!Main.java: Führe alles mithilfe von polymorphem Verhalten auf Basis der Schnittstelle zusammen. Du erhältst zwei Eingaben: einen menschlichen Namen und ein Robotermodell. Erstelle einen Human und einen Robot und speichere sie anschließend in einem Array ausSpeaker-Referenzen. Durchlaufe das Array und gib das Ergebnis des Aufrufs vonspeak()für jeden Lautsprecher aus.
Du erhältst zwei Eingaben: den Namen des Menschen (String) und das Modell des Roboters (String).
Deine Ausgabe sollte zwei Zeilen enthalten: eine für jeden Lautsprecher. Beachte, wie sowohl Human als auch Robot über die Speaker-Schnittstelle einheitlich behandelt werden können, obwohl sie auf völlig unterschiedliche Weise sprechen!
Probier es selbst
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Eingaben lesen
String humanName = scanner.nextLine();
String robotModel = scanner.nextLine();
// TODO: Erstelle ein Human-Objekt mit dem gegebenen Namen
// TODO: Erstelle ein Robot-Objekt mit dem gegebenen Modell
// TODO: Erstelle ein Array von Speaker-Referenzen, das beide Objekte enthält
// TODO: Durchlaufe das Array und gib das Ergebnis von speak() für jeden Speaker aus
}
}
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