In letzter Zeit habe ich einige Erfahrungen mit der Zuweisung von Unterklassenobjekten zu übergeordneten Klassenobjekten gesammelt und möchte diese mit Ihnen teilen. Mein Niveau ist jedoch begrenzt. Bitte korrigieren Sie mich und kritisieren Sie mich.
Näher zu Hause, hier sind ein paar kleine Beispiele, schauen Sie sich bitte um.
Testen Sie eins
Elternklasse:
Unterklasse:
Ergebnis: Dies ist die print()-Methode der übergeordneten Klasse – das Objekt ist zu diesem Zeitpunkt Subclass@126b249
Zu diesem Zeitpunkt ist das Objekt Subclass@126b249
veranschaulichen:
Supclass sup=new Subclass();
Obwohl das deklarierte Objekt ein übergeordnetes Klassenobjekt ist, gehört der tatsächliche Speicherplatz zum Unterklassenobjekt.
Die von der übergeordneten Klasse geerbte Methode public void print() wird aufgerufen und die Ausgabe ist die Namensauflösung des Unterklassenobjekts.
Fazit: Das zur Kompilierungszeit deklarierte Objekt ist ein übergeordnetes Klassenobjekt, aber zur Laufzeit ist es ein Unterklassenobjekt. Wenn die Unterklasse die Methode der übergeordneten Klasse nicht überschreibt, ruft das Objekt zu diesem Zeitpunkt die von der übergeordneten Klasse geerbte Methode auf.
Test 2
Elternklasse:
Unterklasse:
Ergebnis: Dies ist die print()-Methode der Unterklasse – zu diesem Zeitpunkt ist das Objekt Subclass@126b249
Zu diesem Zeitpunkt ist das Objekt Subclass@126b249
veranschaulichen:
Basierend auf dem vorherigen Beispiel habe ich die print()-Methode der übergeordneten Klasse neu geschrieben. Zu diesem Zeitpunkt wurde die print()-Methode der Unterklasse aufgerufen.
Schlussfolgerung: Basierend auf der Schlussfolgerung des vorherigen Beispiels bin ich zu dem Schluss gekommen, dass das Objekt zu diesem Zeitpunkt tatsächlich ein Unterklassenobjekt ist, wenn die Unterklasse nicht die Methode der übergeordneten Klasse schreibt.
Dann ruft das Objekt zu diesem Zeitpunkt die von der übergeordneten Klasse geerbte Methode auf. Andernfalls ruft das Objekt zu diesem Zeitpunkt die Methode der Unterklasse auf.
Frage: Können wir aus dem obigen Test die folgende Schlussfolgerung ziehen: Weisen Sie das Unterklassenobjekt dem übergeordneten Klassenobjekt zu (d. h. Supclass sup=new Subclass()),
Was wir erhalten, ist ein Unterklassenobjekt, das heißt, sup ist ein Unterklassenobjekt ??????
Test drei
Elternklasse:
Unterklasse:
Ergebnis: Attribute zu diesem Zeitpunkt: Attribute der übergeordneten Klasse
Hinweis: Basierend auf dem ersten Test habe ich der übergeordneten Klasse ein Attribut „className“ hinzugefügt und dieses Attribut in der Unterklasse überschrieben.
Wenn ich jedoch zu diesem Zeitpunkt die Eigenschaften des Objekts ausgebe, handelt es sich um die Eigenschaften der übergeordneten Klasse.
Fazit: Bei der Zuweisung von Unterklassenobjekten zu übergeordneten Klassenobjekten unterscheiden sich die Methoden und Eigenschaften stark von unserer orthodoxen Vererbungsbeziehung.
Frage:
Ist das Objekt zu diesem Zeitpunkt ein Unterklassenobjekt oder ein übergeordnetes Klassenobjekt?
Fangen Sie an zu spekulieren:
Bevor ich spekuliere, muss ich einige Punkte anmerken:
1. Wenn wir ein neues Unterklassenobjekt erstellen, wird gleichzeitig auch der Konstruktor des übergeordneten Klassenobjekts ausgeführt, dh einige notwendige Informationen der übergeordneten Klasse und des Unterklassenobjekts belegen denselben Speicherplatz.
Wenn wir die Methode überschreiben, können wir das Superobjekt verwenden, um auf die übergeordnete Klasse zu verweisen.
2. Objekte in Java sind nicht vollständig objektorientiert, das heißt, die Attribute und Methoden eines Objekts werden nicht gleichzeitig in das Objekt gekapselt.
Das Objekt hat jedoch seine eigenen Attribute, aber die Methode verweist auf die Methode in der Klasse. Man kann sagen, dass sie die Referenzen der Attribute und Methoden in der Klasse in das Objekt einkapselt.
Die vom Objekt aufgerufene Methode ist also nicht ihre eigene Methode, sondern die Methode in der Klasse. Warum Java dies tut, weiß ich nicht.
3. Wenn das Objekt in den Speicher geladen wird, wird die Klasse zuerst in den Speicher geladen und dann sollte die Klasse im Speicher bleiben. Ich weiß nicht, wann die Klasse aus dem Speicher verschwindet.
Ich denke, Java muss über einen eigenen Recyclingmechanismus verfügen, genau wie das Recycling von Objekten.
4. Kompilieren und Ausführen sind völlig unterschiedliche Dinge. Die wichtigsten Dinge, die Sie während der Kompilierung tun, sind die Deklaration des Objekttyps, die Zuweisung von Attributen, die Prüfung auf Syntaxfehler usw.
Was die Laufzeit tut, ist das Laden von Objekten in den Speicher (normalerweise mit new, häufig wird auch Reflection verwendet), das Ausführen von Codeausführungsfunktionen usw.
5. Wenn Sie, der Leser, und ich uns in diesen Punkten nicht einig sind oder wenn wir in diesen Punkten nicht das gleiche Verständnis haben, werden Sie denken, dass ich Unsinn rede.
Vielleicht denken Sie, dass meine Expertenbewertung zu niedrig ist und daher meine Glaubwürdigkeit gering ist. Was ich jedoch sagen möchte, ist, dass es keine Reihenfolge beim Lernen gibt und diejenigen, die zuerst beherrschen, zuerst kommen.
Haha, ich bin bereit, meine Expertenpunkte in negative Werte umzuwandeln, kein Unsinn mehr, lasst uns weitermachen.
Spekulation:
1. Wenn wir Supclass sup=new Subclass() kompilieren, wird das Sup-Objekt als Supclass-Klasse deklariert, sodass die Attribute des Sup-Objekts die Werte der Attribute des übergeordneten Klassenobjekts sind.
3. Wenn wir ab Schritt 2 fortfahren und die Methode der übergeordneten Klasse überschreiben, wurde die Unterklassenmethode public void print() in den Speicher geladen, da der Speicherplatz des Sup-Objekts der Speicherplatz des Unterklassenobjekts ist.
Was wir also aufrufen, ist die Methode public void print() der Unterklasse; wenn Sie die überschriebene Methode der übergeordneten Klasse aufrufen müssen, müssen Sie super verwenden.
Diese Passage kann Test 2 erklären.
Zusammenfassen:
Im Folgenden handelt es sich um rein persönliche Meinungen:
Weisen Sie das Unterklassenobjekt dem übergeordneten Klassenobjekt zu, und das resultierende Objekt ist ein Objekt wie dieses:
Es wird als übergeordnetes Klassenobjekt kompiliert, aber als Unterklassenobjekt ausgeführt. Die spezifischen Merkmale sind wie folgt.
1. Als übergeordnetes Klassenobjekt deklariert 2. Hat übergeordnete Klassenattribute 3. Belegt den Speicherplatz der Unterklasse 4. Wenn die Unterklassenmethode die übergeordnete Klassenmethode überschreibt, ruft das Objekt zu diesem Zeitpunkt die Unterklassenmethode auf, andernfalls erfolgt die Vererbung automatisch namens Methoden der übergeordneten Klasse.
5. Ich denke, dieses Objekt ist weder ein übergeordnetes Klassenobjekt noch ein untergeordnetes Klassenobjekt. Wenn wir seine Methoden verwenden,
Ich behandle es als Unterklassenobjekt. Wenn ich seine Eigenschaften verwende, behandle ich es als übergeordnetes Klassenobjekt.
Es ist ein Objekt, das die Attribute der übergeordneten Klasse belegt und die Methoden der untergeordneten Klasse verwendet. Ich denke, es hängt von der Deklaration ab. Es sollte als übergeordnetes Klassenobjekt betrachtet werden, hat aber eine Unterklasse Methoden.
Denken Sie darüber nach:
Wie extrahieren wir basierend auf Test 3 die Attribute der Unterklasse? ? ? ? ?