Interfaces implementieren
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 35 von 87.
Um ein Interface zu verwenden, muss eine Klasse dieses unter Verwendung des Schlüsselworts implements implementieren. Die Klasse stellt dann konkrete Implementierungen für alle im Interface 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, wird der Compiler einen Fehler ausgeben. Die @Override-Annotation ist optional, wird aber empfohlen, da sie hilft, Fehler zu erkennen.
Genau wie bei abstrakten Klassen können Sie ein Interface als Referenztyp verwenden. Dies ermöglicht Polymorphie, bei der 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(); // Zeichnet einen Kreis mit dem Radius 5.0
shape2.draw(); // Zeichnet ein Rechteck 4.0 x 3.0Dies ist leistungsstark, da Code, der mit Drawable-Referenzen arbeitet, den spezifischen Klassentyp nicht kennen muss. Es ist nur wichtig, dass das Objekt gezeichnet werden kann.
In der nächsten Lektion werden Sie sehen, wie eine einzelne Klasse mehrere Interfaces gleichzeitig implementieren kann.
Aufgabe
EinfachLassen Sie uns ein Lautsprechersystem bauen, das demonstriert, wie Klassen Interfaces implementieren. Sie werden ein Interface erstellen, das definiert, was jeder Lautsprecher tun kann, und dann zwei verschiedene Lautsprechertypen bauen, die diesen Vertrag jeweils auf ihre eigene Weise implementieren.
Sie werden Ihren Code über vier Dateien organisieren:
Speaker.java: Definieren Sie ein Interface namensSpeaker, das deklariert, was jeder Lautsprecher können muss. Jeder Lautsprecher sollte einespeak()-Methode haben, die einen String zurückgibt – dies ist der Vertrag, den alle implementierenden Klassen erfüllen müssen.Human.java: Erstellen Sie eine Klasse, die dasSpeaker-Interface implementiert. Ein Human hat einname-Feld (String). Fügen Sie einen Konstruktor hinzu, um den Namen zu initialisieren, und implementieren Sie diespeak()-Methode so, dass sie Folgendes zurückgibt:[name] says: Hello everyone!Robot.java: Erstellen Sie eine weitere Klasse, die dasSpeaker-Interface implementiert. Ein Robot hat einmodel-Feld (String). Fügen Sie einen Konstruktor hinzu, um das Modell zu initialisieren, und implementieren Sie diespeak()-Methode so, dass sie Folgendes zurückgibt:Robot [model] says: Beep boop!Main.java: Bringen Sie alles mithilfe von Interface-basierter Polymorphie zusammen. Sie erhalten zwei Eingaben: einen menschlichen Namen und ein Robotermodell. Erstellen Sie einen Human und einen Robot und speichern Sie diese dann in einem Array vonSpeaker-Referenzen. Gehen Sie in einer Schleife durch das Array und geben Sie das Ergebnis des Aufrufs vonspeak()für jeden Lautsprecher aus.
Sie erhalten zwei Eingaben: den Namen des Menschen (String) und das Modell des Roboters (String).
Ihre Ausgabe sollte zwei Zeilen zeigen – eine für jeden Lautsprecher. Beachten Sie, wie sowohl der Human als auch der Robot einheitlich über das Speaker-Interface behandelt werden können, obwohl sie auf völlig unterschiedliche Weise sprechen!
Spickzettel
Eine Klasse verwendet das Schlüsselwort implements, um ein Interface zu implementieren, und muss konkrete Implementierungen für alle im Interface deklarierten Methoden bereitstellen:
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);
}
}Die Annotation @Override ist optional, wird aber empfohlen, da sie hilft, Fehler zu erkennen.
Interfaces können als Referenztypen verwendet werden, was Polymorphismus ermöglicht, 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(); // Zeichnet einen Kreis mit Radius 5.0
shape2.draw(); // Zeichnet ein Rechteck 4.0 x 3.0Probier 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 angegebenen Namen
// TODO: Erstelle ein Robot-Objekt mit dem angegebenen Modell
// TODO: Erstelle ein Array aus 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 this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem