Ich bin seit zwei Jahren .NET-Programmierer (kann nicht sagen, dass ich Programmierer bin). Es gibt eine Frage, die ich seit Jahren nicht verstehen kann. So könnte eine Instanz der Basisklasse eine Instanz der abgeleiteten Klasse enthalten.
Angenommen wir haben zwei Klassen:
%Vor%Wie konnte das passieren?
%Vor% Ich meine, das Speichermodell von BaseClass
hat keinen Platz für die neu hinzugefügte Eigenschaft c, also wie könnte es noch den Wert von propertyC enthalten?
Auf der anderen Seite, wie könnte das nicht passieren:
%Vor% Ich dachte, das ist der richtige Weg, da das Speichermodell von DerivedClass
alle Leerzeichen für die BaseClass und noch mehr hat. Aber das ist nicht wahr, warum?
Ich weiß, dass ich eine wirklich dumme Frage stelle, aber könnte mir jemand eine genauere Antwort geben? Es wäre besser aus der Perspektive des Speichers oder Compilers.
Weil (und dieses Konzept oft missverstanden wird) wird die Variable, die den Zeiger enthält, unabhängig vom tatsächlichen konkreten Typ des Objekts, auf das sie zeigt, eingegeben.
Also wenn du schreibst
%Vor% Der Teil, der BaseClass obj
angibt, erstellt eine neue Referenz Variable im Stack, die der Compiler versteht, um eine Referenz auf etwas zu halten, das von BaseClass
stammt oder abgeleitet wird.
Der Teil, der = new DerivedClass ()
liest, erstellt tatsächlich ein neues Objekt vom Typ DerivedClass
, speichert es auf dem Heap und speichert einen Zeiger auf dieses Objekt in der Speicherort, auf den obj
zeigt. Das tatsächliche Objekt auf dem Heap ist ein DerivedClass
; Dies wird als konkreter Typ des Objekts bezeichnet.
Die Variable obj
wird vom Typ BaseClass
deklariert. Dies ist kein konkreter Typ , sondern nur ein Variablentyp , der den Compiler nur beschränkt, eine Adresse in die Variable zu speichern, die auf zeigt ein Objekt, das kein BaseClass
ist oder das nicht vom Typ BaseClass
abgeleitet ist.
Dies wird getan, um zu garantieren, dass alles, was Sie in die Variable obj eingeben, egal ob es sich um einen konkreten Typ von BaseClass
oder DerivedClass
handelt, alle Methoden, Eigenschaften und andere Member vom Typ% co_de haben %. Es teilt dem Compiler mit, dass alle Verwendungen der Variable BaseClass
auf die Verwendung nur der Member der Klasse obj
beschränkt werden sollten.
Da BaseClass
ein Referenztyp ist, ist obj
kein BaseClass
-Objekt. Es ist eine Referenz für ein BaseClass
-Objekt. Insbesondere ist dies ein Verweis auf den BaseClass
-Teil von DerivedClass
.
Wenn Sie das sagen:
%Vor%Sie sagen NICHT "Erstellen Sie einen Container, der dieses BaseClass-Objekt enthält, und fügen Sie dann dieses größere DerivedClass-Objekt ein".
Sie erstellen tatsächlich ein DerivedClass-Objekt und es wird in einem Speicherbereich erstellt, der für ein DerivedClass-Objekt ausreicht. Niemals verliert das .NET-Framework den Überblick über die Tatsache, dass dieses Ding speziell eine DerivedClass ist, noch hört es auf, es als solches zu behandeln.
Wenn Sie jedoch angeben, eine BaseClass-Objektvariable zu verwenden, erstellen Sie lediglich einen Verweis / Zeiger auf das Objekt, das bereits erstellt und zugewiesen und definiert wurde, und alles, und Ihr Zeiger ist nur ein wenig vager .
Es ist, als ob der Typ da drüben auf der anderen Seite des Raumes ein rothaariger irischer, leicht übergewichtiger Hühnerbauer mit schlechten Zähnen und charmanter Persönlichkeit namens Jimmy ist, aber Sie bezeichnen ihn nur als "diesen Kerl da drüben ". Die Tatsache, dass Sie ihn vage beschreiben, ändert nichts an dem, was er ist, oder an seinen Details, auch wenn Ihre vage Beschreibung genau ist.
Antwort wurde wortwörtlich kopiert von dem, was ein anderer Benutzer, jk, in Stackofflow auf genau die gleiche Frage geschrieben hat.
Wenn ich dir sage, dass ich einen Hund habe, kannst du davon ausgehen, dass ich einen Hund habe.
Wenn ich dir sage, dass ich ein Haustier habe, weißt du nicht, ob dieses Tier ein Hund ist könnte eine Katze oder vielleicht sogar eine Giraffe sein. Ohne etwas extra zu wissen Informationen, die Sie nicht sicher annehmen können, habe ich einen Hund.
Ähnlich ist ein abgeleitetes Objekt ein Basisklassenobjekt (als ein Sub-Objekt Klasse), auf die ein Basisklassenzeiger zeigen kann. aber eine Basis Das Klassenobjekt ist kein abgeleitetes Klassenobjekt und kann daher keinem a zugewiesen werden abgeleiteter Klassenzeiger.
(Das Knarren, das Sie jetzt hören werden, ist die Analogie, die sich ausdehnt)
Angenommen, Sie möchten mir jetzt ein Geschenk für mein Haustier kaufen.
Im ersten Szenario weißt du, dass es ein Hund ist, du kannst mir eine Leine kaufen, Jeder ist glücklich.
Im zweiten Szenario habe ich dir nicht gesagt, was mein Haustier ist, wenn du es bist Werde mir sowieso ein Geschenk kaufen, du musst Informationen wissen, die ich nicht habe habe dir gesagt (oder rate mal), du kaufst mir eine Leine, wenn es mir wirklich gelingt Hatte einen Hund alle sind glücklich.
Wenn ich jedoch tatsächlich eine Katze hatte, wissen wir jetzt, dass du eine schlechte Sache gemacht hast Annahme (Cast) und eine unglückliche Katze an der Leine haben (Laufzeitfehler)
Dies ist möglich, weil Speicher für Basis- und abgeleitete Klassen reserviert ist. In einer abgeleiteten Klasse werden die Instanzvariablen der Basisklasse zuerst zugewiesen, gefolgt von den Instanzvariablen der abgeleiteten Klasse. Wenn eine Basisklassenreferenzvariable einem abgeleiteten Klassenobjekt zugewiesen wird, sieht sie die erwarteten Basisklasseninstanzvariablen und die "zusätzlichen" abgeleiteten Klasseninstanzvariablen.
Tags und Links .net inheritance oop derived-class