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?
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?
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 AbstractShape
die 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:
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 ChildB
aber 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 …
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
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:
…
RelationalerAusdruck Instanzvon Referenztyp15.20.2. Geben Sie den Vergleichsoperator instanceof ein
…
Zur Laufzeit wird das Ergebnis derinstanceof
Betreiber isttrue
wenn der Wert der RelationalerAusdruck ist nichtnull
und der Verweis könnte auf die gegossen werden Referenztyp ohne a zu erhöhenClassCastException
. Ansonsten ist das Ergebnisfalse
.