Ich frage mich, was der Unterschied zwischen den folgenden ist:
Fall 1: Basisklasse
public void DoIt();
Fall 1: Vererbte Klasse
public new void DoIt();
Fall 2: Basisklasse
public virtual void DoIt();
Fall 2: Vererbte Klasse
public override void DoIt();
Sowohl Fall 1 als auch Fall 2 scheinen auf der Grundlage der von mir durchgeführten Tests den gleichen Effekt zu haben. Gibt es einen Unterschied oder einen bevorzugten Weg?
c#
inheritance
overriding
new-operator
Shiraz Bhaiji
quelle
quelle
Antworten:
wird aufrufen,
Derived.DoIt
wenn dies überschreibtBase.DoIt
.Ich rufe
Base.DoIt
dann zuerst anDerived.DoIt
. Es handelt sich effektiv um zwei völlig getrennte Methoden, die zufällig denselben Namen haben, und nicht um die abgeleitete Methode, die die Basismethode überschreibt.Quelle: Microsoft-Blog
quelle
This indicates for the compiler to use the last defined implementation of a method
. Wie kann die zuletzt definierte Implementierung einer Methode gefunden werden?override
eine Methode nur verwenden können, wenn die Basisklasse die Methode als definiertvirtual
. Das Wortvirtual
ist die Basisklasse, die sagt: "Hey, wenn ich diese Methode aufrufe, könnte sie praktisch durch eine abgeleitete Implementierung ersetzt worden sein, daher weiß ich nicht im Voraus, welche Methodenimplementierung ich zur Laufzeit tatsächlichvirtual
aufrufe ein Platzhalter für eine Methode. Dies bedeutet, dass Methoden, die nicht als markiertvirtual
sind, nicht überschrieben werden können. Sie können jedoch jede nicht virtuelle Methode in einer abgeleiteten Klasse durch den Modifikator ersetzennew
, auf den nur auf abgeleiteter Ebenevirtuell : Gibt an, dass eine Methode möglicherweise von einem Erben überschrieben wird
überschreiben : Überschreibt die Funktionalität einer virtuellen Methode in einer Basisklasse und bietet unterschiedliche Funktionen.
neu : verbirgt die ursprüngliche Methode (die nicht virtuell sein muss) und bietet unterschiedliche Funktionen. Dies sollte nur verwendet werden, wenn dies unbedingt erforderlich ist.
Wenn Sie eine Methode ausblenden, können Sie weiterhin auf die ursprüngliche Methode zugreifen, indem Sie das Casting in die Basisklasse durchführen. Dies ist in einigen Szenarien nützlich, aber gefährlich.
quelle
override
und / odernew
ohnevirtual
die übergeordnete Methode verwenden?Im ersten Fall verstecken Sie die Definition in der übergeordneten Klasse. Dies bedeutet, dass es nur aufgerufen wird, wenn Sie das Objekt als untergeordnete Klasse behandeln. Wenn Sie die Klasse in ihren übergeordneten Typ umwandeln, wird die übergeordnete Methode aufgerufen. In der zweiten Instanz wird die Methode überschrieben und unabhängig davon aufgerufen, ob das Objekt als untergeordnete oder übergeordnete Klasse umgewandelt wird.
quelle
Versuchen Sie Folgendes: (case1)
Bearbeiten: Virtual + Override werden zur Laufzeit aufgelöst (Override überschreibt also wirklich virtuelle Methoden), während New nur eine neue Methode mit demselben Namen erstellt und die alte verbirgt, wird sie zur Kompilierungszeit aufgelöst -> Ihr Compiler nennt die Methode it ' sieht '
quelle
In Fall 1, wenn Sie die DoIt () -Methode der geerbten Klasse aufgerufen haben, während der Typ als Basisklasse deklariert ist, wird die Aktion der Basisklasse sogar angezeigt.
quelle
Der Unterschied zwischen den beiden Fällen besteht darin, dass in Fall 1 die Basismethode
DoIt
nicht überschrieben, sondern nur ausgeblendet wird. Dies bedeutet, dass abhängig vom Typ der Variablen davon abhängt, welche Methode aufgerufen wird. Beispielsweise:Dies kann sehr verwirrend sein und zu unerwartetem Verhalten führen und sollte nach Möglichkeit vermieden werden. Der bevorzugte Weg wäre also Fall 2.
quelle
Meine Art, beide Schlüsselwörter zu berücksichtigen, dass sie sich gegenüberstehen.
override
Dasvirtual
Schlüsselwort : muss definiert werden, um die Methode zu überschreiben. Die Methode mit demoverride
Schlüsselwort, dass unabhängig vom Referenztyp (Referenz der Basisklasse oder abgeleiteten Klasse) die Methode der Basisklasse ausgeführt wird, wenn sie mit der Basisklasse instanziiert wird. Andernfalls wird die Methode der abgeleiteten Klasse ausgeführt.new
: Wenn das Schlüsselwort von einer Methode verwendet wird, ist im Gegensatz zumoverride
Schlüsselwort der Referenztyp wichtig. Wenn es mit einer abgeleiteten Klasse instanziiert wird und der Referenztyp Basisklasse ist, wird die Methode der Basisklasse ausgeführt. Wenn es mit einer abgeleiteten Klasse instanziiert wird und der Referenztyp eine abgeleitete Klasse ist, wird die Methode der abgeleiteten Klasse ausgeführt. Es ist nämlich der Kontrast desoverride
Schlüsselworts. Wenn Sie vergessen oder unterlassen, der Methode ein neues Schlüsselwort hinzuzufügen, verhält sich der Compiler standardmäßig so, wie dasnew
Schlüsselwort verwendet wird.Rufen Sie in main:
Ausgabe:
Neues Codebeispiel,
Spielen Sie mit dem Code, indem Sie ihn einzeln kommentieren.
quelle
Wenn das Schlüsselwort
override
in der Ableitungsklasse verwendet wird, überschreibt es die übergeordnete Methode.Wenn das Schlüsselwort
new
in der Ableitungsklasse verwendet wird, wird die von der übergeordneten Methode ausgeblendete Methode abgeleitet.quelle
Ich hatte die gleiche Frage und es ist wirklich verwirrend. Sie sollten berücksichtigen, dass Override und neue Schlüsselwörter nur mit Objekten vom Typ Basisklasse und Wert der abgeleiteten Klasse funktionieren. In diesem Fall wird nur werden Sie die Wirkung von Überschreibung und neu sehen: Also , wenn Sie
class A
undB
,B
erbt vonA
, dann instanziiert Sie ein Objekt wie folgt aus :Beim Aufruf von Methoden wird nun der Status berücksichtigt. Überschreiben : bedeutet, dass die Funktion der Methode erweitert wird und dann die Methode in der abgeleiteten Klasse verwendet wird, während new den Compiler anweist, die Methode in der abgeleiteten Klasse auszublenden und stattdessen die Methode in der Basisklasse zu verwenden. Hier ist ein sehr guter Anblick zu diesem Thema:
https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396
quelle
Der folgende Artikel ist in vb.net, aber ich denke, die Erklärung zu neuen oder Überschreibungen ist sehr einfach zu verstehen.
https://www.codeproject.com/articles/17477/the-dark-shadow-of-overrides
Irgendwann im Artikel gibt es diesen Satz:
Die akzeptierte Antwort auf diese Frage ist perfekt, aber ich denke, dieser Artikel bietet gute Beispiele, um die Unterschiede zwischen diesen beiden Schlüsselwörtern besser zu verstehen.
quelle
Von all diesen neu am verwirrendsten. Durch das Experimentieren gibt das neue Schlüsselwort Entwicklern die Möglichkeit, die Implementierung der geerbten Klasse mit der Implementierung der Basisklasse zu überschreiben, indem der Typ explizit definiert wird. Es ist wie umgekehrt zu denken.
Im folgenden Beispiel gibt das Ergebnis "Abgeleitetes Ergebnis" zurück, bis der Typ explizit als BaseClass-Test definiert ist. Erst dann wird "Basisergebnis" zurückgegeben.
quelle
Der Funktionsunterschied wird in diesen Tests nicht gezeigt:
In diesem Beispiel ist das aufgerufene Doit dasjenige, von dem Sie erwarten, dass es aufgerufen wird.
Um den Unterschied zu erkennen, müssen Sie Folgendes tun:
Sie werden sehen, wenn Sie diesen Test ausführen, dass in Fall 1 (wie Sie ihn definiert haben) das
DoIt()
InBaseClass
aufgerufen wird, in Fall 2 (wie Sie es definiert haben) dasDoIt()
InDerivedClass
aufgerufen wird.quelle
Im ersten Fall wird die DoIt () -Methode der abgeleiteten Klasse aufgerufen, da das neue Schlüsselwort die DoIt () -Methode der Basisklasse verbirgt.
Im zweiten Fall wird überschriebenes DoIt () aufgerufen.
Lassen Sie eine Instanz dieser Klassen erstellen
Alles wird oben erwartet. Setzen Sie instanceB und instanceC auf instanceA und rufen Sie die DoIt () -Methode auf und überprüfen Sie das Ergebnis.
quelle
Alle Kombinationen von none, virtual, override, new und abstract:
quelle