Gibt instanceof true zurück, wenn die Instanz eines übergeordneten Elements?

Lesezeit: 6 Minuten

Benutzer-Avatar
ikbal

ich habe ein klasse Child das erstreckt sich Parent.

Parent child = new Child();

if (child instanceof Parent){
    // Do something
}

Gibt dies wahr oder falsch zurück und warum?

Benutzer-Avatar
Ozair Kafray

Ja, es würde. Und warum sollte es nicht?

Weil child tatsächlich eine Instanz von Parent ist. Wenn Sie eine Operation nur für ein Kind durchführen möchten, sollten Sie dies prüfen

if (child instanceof Child){
}

Sie sollten sich jedoch an die folgende Aussage von Effective C++ von Scott Meyers erinnern:

„Jedes Mal, wenn Sie Code der Form schreiben: „Wenn das Objekt vom Typ T1 ist, dann tun Sie etwas, aber wenn es vom Typ T2 ist, dann tun Sie etwas anderes“, schlagen Sie sich selbst.

was meiner Meinung nach auch in diesem Fall zutrifft. Wenn Sie wollen etwas tun Je nachdem, zu welcher Art von Klasse das referenzierte Objekt gehört, sollte Ihnen die folgende Codestruktur dabei helfen.

HINWEIS: Ich habe es nicht zusammengestellt.

class Parent {
    public void doSomething() {
        System.out.println("I am the Parent, and I do as I like");
    }
}
 
class ChildA extends Parent {
    public void doSomething() {
        System.out.println("I am a child named A, but I have my own ways, different from Parent");
    }
}
 
class ChildB extends Parent {
    public void doSomething() {
        System.out.println("I am a child named B, but I have my own ways, different from my Parent and my siblings");
    }
}
 
public class Polymorphism101 {
 
    public static void main(String[] args) {
 
        Parent p = new Parent();
        p.doSomething();
 
        p = new ChildA();
        p.doSomething();
 
        p = new ChildB();
        p.doSomething();
 
    }
 
}

EDIT: Ein besseres Beispiel

Sie könnten eine entwickeln Zeichnung Anwendung. Eine Anwendung, die Formen jeglicher Art zeichnet. In diesem Fall sollten Sie eine haben abstrakt Typ Shape.

Für Zwecke wie; Zeichnen aller Formen; alle Formen auflisten; Um eine Form zu finden oder eine Form zu löschen, benötigen Sie eine aufführen von Formen. Da es sich bei der Liste um einen übergeordneten Typ handelt, kann sie beliebige Formen speichern.

Das Shape Schnittstelle/abstrakte Klasse/virtuelle Klasse sollte eine haben abstrakt/rein virtuell Funktion Draw(). In Ihrem DrawToDeviceLoop rufen Sie also einfach auf Draw() Für jede Form müssen Sie nie überprüfen, um welche Form es sich handelt.

Das Shape Schnittstelle kann eine haben abstrakt Implementierung AbstractShapedie Shape-Namen oder -IDs als Datenelemente haben können, sowie GetName-, Cleanup- und andere Funktionen mit Funktionen, die allen Shapes gemeinsam sind.

Denken Sie an einen abstrakten Typ kann nicht instanziiert werden, also Shape selbst kann nicht instanziiert werden, da es auch nicht gezeichnet werden kann.

EDIT 2: Polymorphismus und Ausnahmebehandlung – user1955934 fragte: “Was ist mit der Suche nach Ausnahmeklassen?” Für die Ausnahmebehandlung sind die bewährten Methoden in Bezug auf Polymorphismus:

  1. Bestimmte Ausnahmen bevorzugen (auslösen) – Zum Beispiel eine NumberFormatException anstelle von IllegalArgumentException auslösen
  2. Zuerst die spezifischste Ausnahme abfangen – Wenn Sie beispielsweise zuerst eine IllegalArgumentException abfangen, erreichen Sie nie den Catch-Block, der die spezifischere NumberFormatException behandeln sollte, da es sich um eine Unterklasse der IllegalArgumentException handelt.

Es ist also im Prinzip dasselbe, wenn eine Ausnahme anders behandelt werden muss, sollte eine untergeordnete/spezifische Klasse definiert werden, und die spezifische Ausnahme sollte definiert werden erwischt (nicht geprüfte Instanz von)

Um mehr Best Practices für die Ausnahmebehandlung zu erfahren. Sehen 9 Best Practices zur Behandlung von Ausnahmen in Java und Best Practices für Ausnahmen (C#)

EDIT 3: Ich gebe eine Ausnahme in dieser Regel zu

Ich arbeite also mit einem Legacy-Code (geschrieben in C++), der größtenteils vor etwa 15 Jahren geschrieben wurde, wo sie immer prüfen, ob die untergeordnete Klasse bestimmte Aktionen ausführt. Ich wurde gebeten, Code mit der gleichen Logik hinzuzufügen, und ich sagte meinem Manager (er ist auch ein Entwickler), dass ich dies nicht tun kann, und wies auf diese Antwort hin, und dann diskutierten und akzeptierten wir diese Ausnahme von der Regel. In unserem Fall hatte diese Elternklasse seit dem Jahr 2000 nur 2 Kinder, und wir sehen kein Kind, das in naher Zukunft hinzugefügt wird, da der Kerncode auf Wachstum beschränkt ist, haben wir entschieden, dass wir die Kinderklassen und den Strom nicht hinzufügen Da die Zahl nur 2 ist, ist es effizienter, den Typ zu überprüfen, insbesondere wenn der Code seit jeher so geschrieben wurde.

Es gibt jedoch auch nicht viele Instanzen dieser Prüfung, der übergeordnete Code implementiert meistens die komplizierten Funktionalitäten und dient eher dazu, Code zu teilen, als ihn zu spezialisieren/differenzieren.

  • aber ich bestimme den Objekttyp zur Laufzeit und muss eine übergeordnete Referenz definieren, um alle Arten von untergeordneten Objekten aufzunehmen. wie kann ich das anders machen?

    – ikbal

    10. Juni 2011 um 9:12 Uhr

  • @user479129: Sie können einen Verweis auf alle untergeordneten Elemente eines übergeordneten Elements in einem Verweis vom Typ übergeordnetes Element speichern. Das heißt, wenn es eine gibt class Parent {} und class ChildA extends Parent und class ChildB extends Parent dann kannst du verwenden Parent p um auf ein Objekt des Typs zu verweisen ChildA oder ChildBaber ich verstehe nicht, was du mit umgekehrt meinst.

    – Ozair Kafray

    10. Juni 2011 um 9:48 Uhr

  • Ich muss kontrollieren, dass Objekt p ein Typ seines Kindes ist, nicht des Elternteils. In einigen Fällen kann es sich um den übergeordneten Typ handeln, also muss ich überprüfen, ob es genau der Typ ist, den ich möchte. Das ist was ich will. Ich hoffe es ist klar

    – ikbal

    10. Juni 2011 um 11:36 Uhr

  • Ich hätte auch gerne eine verbesserte Antwort, dies wäre nützlich für die Arbeit mit Frame.getComponents(), anstatt jede einzeln zu behandeln.

    – Jason K.

    22. Februar 2017 um 8:18 Uhr

  • @JasonK. Meinst du ein besseres Beispiel?

    – Ozair Kafray

    23. Februar 2017 um 5:42 Uhr

Instanzvon wird true zurückgeben, wenn es eine Unterklasse ist …

Instanz der Dokumentation

  • Und jetzt ist diese Frage immer wahr. Dank

    – Nguyên Ngô Duy

    27. August 2020 um 7:06 Uhr

natürlich gibt es true zurück, weil child eine Instanz des Elternteils ist

  • Ja, java jede Rückgabe wahr, wenn das Kind eine Instanz des Elternteils (oder der Implementierung) ist.

    – Nguyên Ngô Duy

    27. August 2020 um 7:05 Uhr


Benutzer-Avatar
Roland

Ja. instanceof ist wahr, wenn die Referenz (linke Seite der instanceof Ausdruck) kann in die umgewandelt werden Referenztyp(der Typ auf der rechten Seite der instanceof Ausdruck). Dies gilt für Unterklassen in Bezug auf ihre Eltern:

Child child = new Child();
Parent parent = (Parent) child; //works!
assert child instanceof Parent; //true

Aus Die Java-Sprachspezifikation, Java SE 9 Edition:

15.20. Vergleichsoperatoren


RelationalerAusdruck Instanzvon Referenztyp

15.20.2. Geben Sie den Vergleichsoperator instanceof ein


Zur Laufzeit wird das Ergebnis der instanceof Betreiber ist true wenn der Wert der RelationalerAusdruck ist nicht null und der Verweis könnte auf die gegossen werden Referenztyp ohne a zu erhöhen ClassCastException. Ansonsten ist das Ergebnis false.

1381150cookie-checkGibt instanceof true zurück, wenn die Instanz eines übergeordneten Elements?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy