Einführung
In diesem Lab lernen Sie, wie Sie prüfen können, ob ein Objekt in Java eine bestimmte Schnittstelle (Interface) implementiert. Wir werden die Verwendung des Schlüsselworts instanceof untersuchen, ein grundlegendes Werkzeug für die Laufzeittypüberprüfung.
Durch praktische Übungen wenden Sie instanceof an, um die Schnittstellenimplementierung zu überprüfen, Szenarien mit mehreren Schnittstellen zu testen und Fälle mit null-Objekten oder Objekten, die die Schnittstelle nicht implementieren, zu behandeln. In diesem Lab erhalten Sie praktische Fähigkeiten zur Bestimmung des tatsächlichen Typs eines Objekts und zur Nutzung von Schnittstellen-spezifischen Funktionen.
Verwenden Sie instanceof für die Schnittstellenprüfung
In diesem Schritt werden wir untersuchen, wie man das Schlüsselwort instanceof in Java verwendet, um zu prüfen, ob ein Objekt eine Instanz einer bestimmten Schnittstelle (Interface) ist. Dies ist eine häufige Aufgabe, wenn Sie eine Variable vom Typ einer Basisklasse oder Schnittstelle haben und den tatsächlichen Typ des Objekts bestimmen müssen, auf das sie verweist, insbesondere wenn Sie Methoden aufrufen möchten, die spezifisch für eine bestimmte Schnittstelle sind.
Zunächst definieren wir eine einfache Schnittstelle und eine Klasse, die sie implementiert.
Öffnen Sie den WebIDE-Editor.
Stellen Sie im Dateiexplorer links sicher, dass Sie sich im Verzeichnis
~/projectbefinden.Erstellen Sie eine neue Datei mit dem Namen
Printable.java. Sie können dies tun, indem Sie im Dateiexplorer mit der rechten Maustaste klicken und "Neue Datei" auswählen, und dannPrintable.javaeingeben.Öffnen Sie
Printable.javaund fügen Sie den folgenden Code hinzu:package project; public interface Printable { void print(); }Dies definiert eine einfache Schnittstelle namens
Printablemit einer Methode,print().Speichern Sie die Datei (Strg+S oder Cmd+S).
Jetzt erstellen wir eine Klasse, die die Printable-Schnittstelle implementiert.
Erstellen Sie im Verzeichnis
~/projecteine neue Datei mit dem NamenDocument.java.Öffnen Sie
Document.javaund fügen Sie den folgenden Code hinzu:package project; public class Document implements Printable { private String content; public Document(String content) { this.content = content; } @Override public void print() { System.out.println("Printing Document: " + content); } }Diese Klasse
Documentimplementiert diePrintable-Schnittstelle und bietet eine Implementierung für dieprint()-Methode.Speichern Sie die Datei.
Schließlich erstellen wir eine Hauptklasse, um die Verwendung von instanceof mit der Schnittstelle zu demonstrieren.
Erstellen Sie im Verzeichnis
~/projecteine neue Datei mit dem NamenInterfaceCheck.java.Öffnen Sie
InterfaceCheck.javaund fügen Sie den folgenden Code hinzu:package project; public class InterfaceCheck { public static void main(String[] args) { Object obj1 = new Document("Important Report"); Object obj2 = "Just a String"; // Check if obj1 is an instance of Printable if (obj1 instanceof Printable) { System.out.println("obj1 implements Printable"); Printable p1 = (Printable) obj1; // Cast to Printable p1.print(); // Call the print method } else { System.out.println("obj1 does not implement Printable"); } System.out.println("---"); // Check if obj2 is an instance of Printable if (obj2 instanceof Printable) { System.out.println("obj2 implements Printable"); Printable p2 = (Printable) obj2; // This line would cause a ClassCastException if executed p2.print(); } else { System.out.println("obj2 does not implement Printable"); } } }In diesem Code:
- Wir erstellen zwei
Object-Variablen,obj1, die auf einDocument-Objekt verweist (das diePrintable-Schnittstelle implementiert), undobj2, die auf einString-Objekt verweist (das diePrintable-Schnittstelle nicht implementiert). - Wir verwenden
if (obj1 instanceof Printable), um zu prüfen, ob das Objekt, auf dasobj1verweist, eine Instanz derPrintable-Schnittstelle ist. - Wenn dies der Fall ist, geben wir eine Nachricht aus und casten dann
obj1in denPrintable-Typ mit(Printable) obj1. Durch das Casten können wir dasObjectalsPrintablebehandeln und seineprint()-Methode aufrufen. - Wir führen die gleiche Prüfung für
obj2durch. DaStringdiePrintable-Schnittstelle nicht implementiert, wird derelse-Block ausgeführt.
- Wir erstellen zwei
Speichern Sie die Datei.
Jetzt kompilieren und führen wir den Code aus.
Öffnen Sie das Terminal unten im WebIDE. Stellen Sie sicher, dass Sie sich im Verzeichnis
~/projectbefinden.Kompilieren Sie die Java-Dateien:
javac Printable.java Document.java InterfaceCheck.javaWenn keine Fehler auftreten, erstellt dieser Befehl die Dateien
Printable.class,Document.classundInterfaceCheck.class.Führen Sie das
InterfaceCheck-Programm aus:java InterfaceCheckSie sollten eine Ausgabe ähnlich der folgenden sehen:
obj1 implements Printable Printing Document: Important Report --- obj2 does not implement Printable
Diese Ausgabe bestätigt, dass instanceof korrekt erkannt hat, dass obj1 die Printable-Schnittstelle implementiert, während obj2 dies nicht tut. Das Verwenden von instanceof vor dem Casten ist entscheidend, um ClassCastException-Fehler zur Laufzeit zu vermeiden.
Testen mit mehreren Schnittstellen
In diesem Schritt erweitern wir unser Verständnis von instanceof, indem wir mit mehreren Schnittstellen (Interfaces) arbeiten. Eine einzelne Klasse in Java kann mehrere Schnittstellen implementieren, und instanceof kann verwendet werden, um auf jede dieser Schnittstellen zu prüfen.
Zunächst definieren wir eine weitere Schnittstelle.
Öffnen Sie den WebIDE-Editor.
Erstellen Sie im Verzeichnis
~/projecteine neue Datei mit dem NamenEditable.java.Öffnen Sie
Editable.javaund fügen Sie den folgenden Code hinzu:package project; public interface Editable { void edit(String newContent); }Dies definiert eine Schnittstelle namens
Editablemit einer Methode,edit().Speichern Sie die Datei.
Jetzt ändern wir unsere Document-Klasse, um sowohl Printable als auch Editable zu implementieren.
Öffnen Sie die Datei
Document.javaim Verzeichnis~/project.Ändern Sie die Klassendeklaration, um beide Schnittstellen zu implementieren:
package project; public class Document implements Printable, Editable { private String content; public Document(String content) { this.content = content; } @Override public void print() { System.out.println("Printing Document: " + content); } @Override public void edit(String newContent) { this.content = newContent; System.out.println("Document edited."); } }Wir haben
, Editablezur Klassendeklaration hinzugefügt und eine Implementierung für dieedit()-Methode bereitgestellt.Speichern Sie die Datei.
Als Nächstes ändern wir unsere Hauptklasse InterfaceCheck.java, um auf beide Schnittstellen zu testen.
Öffnen Sie die Datei
InterfaceCheck.javaim Verzeichnis~/project.Ersetzen Sie den vorhandenen Code durch den folgenden:
package project; public class InterfaceCheck { public static void main(String[] args) { Object obj1 = new Document("Initial Content"); Object obj2 = "Just a String"; System.out.println("Checking obj1:"); // Check if obj1 is an instance of Printable if (obj1 instanceof Printable) { System.out.println("obj1 implements Printable"); Printable p1 = (Printable) obj1; p1.print(); } else { System.out.println("obj1 does not implement Printable"); } // Check if obj1 is an instance of Editable if (obj1 instanceof Editable) { System.out.println("obj1 implements Editable"); Editable e1 = (Editable) obj1; // Cast to Editable e1.edit("Modified Content"); // Call the edit method // After editing, let's print again to see the change if (obj1 instanceof Printable) { // We know it is, but demonstrating Printable p1_after_edit = (Printable) obj1; p1_after_edit.print(); } } else { System.out.println("obj1 does not implement Editable"); } System.out.println("---"); System.out.println("Checking obj2:"); // Check if obj2 is an instance of Printable if (obj2 instanceof Printable) { System.out.println("obj2 implements Printable"); // Printable p2 = (Printable) obj2; // Would cause ClassCastException // p2.print(); } else { System.out.println("obj2 does not implement Printable"); } // Check if obj2 is an instance of Editable if (obj2 instanceof Editable) { System.out.println("obj2 implements Editable"); // Editable e2 = (Editable) obj2; // Would cause ClassCastException // e2.edit("Some Content"); } else { System.out.println("obj2 does not implement Editable"); } } }In diesem aktualisierten Code prüfen wir nun, ob
obj1eine Instanz sowohl vonPrintableals auch vonEditableist. DaDocumentbeide Schnittstellen implementiert, werden beideif-Bedingungen fürobj1wahr sein. Wir demonstrieren auch das Aufrufen deredit()-Methode nach dem Casten zuEditable. Fürobj2(dasString-Objekt) werden beide Prüfungen falsch sein.Speichern Sie die Datei.
Schließlich kompilieren und führen wir den aktualisierten Code aus.
Öffnen Sie das Terminal im Verzeichnis
~/project.Kompilieren Sie die Java-Dateien erneut:
javac Printable.java Editable.java Document.java InterfaceCheck.javaFühren Sie das
InterfaceCheck-Programm aus:java InterfaceCheckSie sollten eine Ausgabe ähnlich der folgenden sehen:
Checking obj1: obj1 implements Printable Printing Document: Initial Content obj1 implements Editable Document edited. Printing Document: Modified Content --- Checking obj2: obj2 does not implement Printable obj2 does not implement Editable
Diese Ausgabe zeigt, dass instanceof korrekt erkannt hat, dass das Document-Objekt (obj1) beide Schnittstellen implementiert, und wir konnten casten und Methoden sowohl von Printable als auch von Editable aufrufen. Das String-Objekt (obj2) hat korrekt gezeigt, dass es keine der beiden Schnittstellen implementiert.
Umgang mit Null- und nicht implementierenden Objekten
In diesem Schritt werden wir untersuchen, wie das Schlüsselwort instanceof verhält, wenn es mit null-Referenzen und Objekten umgeht, die die zu prüfende Schnittstelle (Interface) nicht implementieren. Das Verständnis dieser Fälle ist wichtig für das Schreiben robuster Code.
Ändern wir die Datei InterfaceCheck.java, um eine null-Referenz und ein Objekt einer Klasse einzubeziehen, die weder Printable noch Editable implementiert.
Öffnen Sie die Datei
InterfaceCheck.javaim Verzeichnis~/project.Ersetzen Sie den vorhandenen Code durch den folgenden:
package project; // Assume Printable and Editable interfaces and Document class are already defined public class InterfaceCheck { public static void main(String[] args) { Object obj1 = new Document("Initial Content"); Object obj2 = "Just a String"; // Does not implement Printable or Editable Object obj3 = null; // A null reference Object obj4 = new Object(); // An object that does not implement Printable or Editable System.out.println("Checking obj1 (Document):"); if (obj1 instanceof Printable) { System.out.println("obj1 implements Printable"); } else { System.out.println("obj1 does not implement Printable"); } if (obj1 instanceof Editable) { System.out.println("obj1 implements Editable"); } else { System.out.println("obj1 does not implement Editable"); } System.out.println("---"); System.out.println("Checking obj2 (String):"); if (obj2 instanceof Printable) { System.out.println("obj2 implements Printable"); } else { System.out.println("obj2 does not implement Printable"); } if (obj2 instanceof Editable) { System.out.println("obj2 implements Editable"); } else { System.out.println("obj2 does not implement Editable"); } System.out.println("---"); System.out.println("Checking obj3 (null):"); if (obj3 instanceof Printable) { System.out.println("obj3 implements Printable"); } else { System.out.println("obj3 does not implement Printable"); } if (obj3 instanceof Editable) { System.out.println("obj3 implements Editable"); } else { System.out.println("obj3 does not implement Editable"); } System.out.println("---"); System.out.println("Checking obj4 (Object):"); if (obj4 instanceof Printable) { System.out.println("obj4 implements Printable"); } else { System.out.println("obj4 does not implement Printable"); } if (obj4 instanceof Editable) { System.out.println("obj4 implements Editable"); } else { System.out.println("obj4 does not implement Editable"); } } }In diesem aktualisierten Code haben wir zwei neue
Object-Variablen hinzugefügt:obj3wirdnullzugewiesen.obj4wird eine neue Instanz der BasisklasseObjectzugewiesen, die unsere benutzerdefinierten Schnittstellen nicht implementiert.
Anschließend verwenden wir
instanceof, um jedes dieser Objekte sowohl gegenPrintableals auch gegenEditablezu prüfen.Speichern Sie die Datei.
Jetzt kompilieren und führen wir den aktualisierten Code aus.
Öffnen Sie das Terminal im Verzeichnis
~/project.Kompilieren Sie die Java-Dateien. Da wir nur
InterfaceCheck.javageändert haben, können wir nur diese Datei kompilieren, aber es ist auch in Ordnung, alle drei zu kompilieren:javac Printable.java Editable.java Document.java InterfaceCheck.javaFühren Sie das
InterfaceCheck-Programm aus:java InterfaceCheckSie sollten eine Ausgabe ähnlich der folgenden sehen:
Checking obj1 (Document): obj1 implements Printable obj1 implements Editable --- Checking obj2 (String): obj2 does not implement Printable obj2 does not implement Editable --- Checking obj3 (null): obj3 does not implement Printable obj3 does not implement Editable --- Checking obj4 (Object): obj4 does not implement Printable obj4 does not implement Editable
Beobachten Sie die Ausgabe für obj3 (die null-Referenz). Der instanceof-Operator gibt false zurück, wenn die Objektreferenz null ist, unabhängig vom zu prüfenden Typ. Dies ist ein wichtiges Verhalten von instanceof und verhindert NullPointerException-Fehler bei der Prüfung.
Beobachten Sie auch die Ausgabe für obj4 (das einfache Object). Wie erwartet gibt die instanceof-Prüfung false zurück, da die Object-Klasse weder Printable noch Editable implementiert.
Dieser Schritt zeigt, dass instanceof sicher mit null-Referenzen verwendet werden kann und Objekte, die die angegebene Schnittstelle nicht implementieren, korrekt erkennt.
Zusammenfassung
In diesem Lab haben wir gelernt, wie man in Java mithilfe des Schlüsselworts instanceof prüft, ob ein Objekt eine bestimmte Schnittstelle (Interface) implementiert. Wir begannen damit, eine einfache Schnittstelle (Printable) und eine Klasse (Document) zu definieren, die diese Schnittstelle implementiert. Anschließend haben wir eine Hauptklasse (InterfaceCheck) erstellt, um zu zeigen, wie man instanceof verwendet, um zu überprüfen, ob ein Objekt eine Instanz der Printable-Schnittstelle ist. Diese grundlegende Technik ist entscheidend für das sichere Casten von Objekten und das Aufrufen von Schnittstellen-spezifischen Methoden.
Wir haben die Flexibilität von instanceof weiter untersucht, indem wir Objekte getestet haben, die mehrere Schnittstellen implementieren, und auch Randfälle wie das Umgang mit null-Objekten und Objekten, die die Zielschnittstelle nicht implementieren, berücksichtigt haben. Dieser umfassende Ansatz gewährleistet ein solides Verständnis davon, wie man zuverlässig den Implementierungsstatus einer Schnittstelle eines Objekts in verschiedenen Szenarien feststellen kann.



