Was sind die Unterschiede zwischen dem Deklarieren einer Methode in einem Basistyp " virtual
" und dem anschließenden Überschreiben in einem untergeordneten Typ mit dem override
Schlüsselwort " " im Gegensatz zum einfachen Verwenden des new
Schlüsselworts " " beim Deklarieren der übereinstimmenden Methode im untergeordneten Typ?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
quelle
quelle
new
wird ein neues Mitglied mit demselben Namen erstellt und das ursprüngliche Mitglied wird ausgeblendet, währendoverride
die Implementierung für ein geerbtes Mitglied erweitert wird"Antworten:
Das Schlüsselwort "new" überschreibt nicht, es kennzeichnet eine neue Methode, die nichts mit der Basisklassenmethode zu tun hat.
Dies gibt false aus. Wenn Sie überschreiben verwendet haben, wird true ausgegeben.
(Basiscode von Joseph Daigle)
Wenn Sie also echten Polymorphismus betreiben, sollten Sie IMMER ÜBERSCHREIBEN . Der einzige Ort, an dem Sie "new" verwenden müssen, ist, wenn die Methode in keiner Weise mit der Basisklassenversion zusammenhängt.
quelle
virtual
in der Basis undoverride
in abgeleitet? Warum existiert es? Der Code läuft auch ohne nochnew
- ist er also nur lesbar?Ich finde solche Dinge mit Bildern immer leichter verständlich:
Wiederum den Code von Joseph Daigle nehmen,
Wenn Sie dann den Code wie folgt aufrufen:
HINWEIS: Das Wichtigste ist, dass unser Objekt tatsächlich ein Objekt ist
Bar
, aber wir speichern es in einer Variablen vom TypFoo
(dies ähnelt dem Casting).Das Ergebnis ist dann wie folgt, je nachdem, ob Sie
virtual
/override
odernew
bei der Deklaration Ihrer Klassen verwendet haben.quelle
Hier ist ein Code, um den Unterschied im Verhalten virtueller und nicht virtueller Methoden zu verstehen:
quelle
new
die Basismethode "verstecken", wenn einfach nicht überschrieben zu werden scheint?virtual
und der Compiler sich beschwert, wenn er denselben Funktionsnamen in einer Klasse "Blutlinie" ohnevirtual
SignaturDas
new
Schlüsselwort erstellt tatsächlich ein völlig neues Mitglied, das nur für diesen bestimmten Typ vorhanden ist.Zum Beispiel
Die Methode existiert für beide Typen. Wenn Sie Reflection verwenden und die Mitglieder vom Typ
Bar
abrufen, finden Sie tatsächlich zwei MethodenDoSomething()
, die genau gleich aussehen. Durch die Verwendungnew
verstecken Sie die Implementierung in der Basisklasse effektiv, sodass, wenn Klassen vonBar
(in meinem Beispiel) dem Methodenaufruf to abgeleitet werden,base.DoSomething()
zuBar
und nichtFoo
.quelle
virtual / override teilt dem Compiler mit, dass die beiden Methoden zusammenhängen und dass es unter bestimmten Umständen, wenn Sie glauben, die erste (virtuelle) Methode aufzurufen, tatsächlich richtig ist, stattdessen die zweite (überschriebene) Methode aufzurufen. Dies ist die Grundlage des Polymorphismus.
Ruft die überschriebene VirtualFoo () -Methode der Unterklasse auf.
new teilt dem Compiler mit, dass Sie einer abgeleiteten Klasse eine Methode mit demselben Namen wie eine Methode in der Basisklasse hinzufügen, diese jedoch keine Beziehung zueinander haben.
Ruft die NewBar () -Methode der BaseClass auf, während:
Ruft die NewBar () -Methode der Unterklasse auf.
quelle
Über die technischen Details hinaus vermittelt die Verwendung von Virtual / Override meiner Meinung nach viele semantische Informationen zum Design. Wenn Sie eine Methode als virtuell deklarieren, geben Sie an, dass Sie erwarten, dass implementierende Klassen möglicherweise ihre eigenen, nicht standardmäßigen Implementierungen bereitstellen möchten. Wenn Sie dies in einer Basisklasse weglassen, wird ebenfalls die Erwartung deklariert, dass die Standardmethode für alle implementierenden Klassen ausreichen sollte. Ebenso kann man abstrakte Deklarationen verwenden, um implementierende Klassen zu zwingen, ihre eigene Implementierung bereitzustellen. Auch hier denke ich, dass dies viel darüber aussagt, wie der Programmierer erwartet, dass der Code verwendet wird. Wenn ich sowohl die Basis- als auch die Implementierungsklasse schreiben würde und neue verwenden würde, würde ich die Entscheidung, die Methode im übergeordneten Element nicht virtuell zu machen, ernsthaft überdenken und meine Absicht ausdrücklich erklären.
quelle
Der Unterschied zwischen dem Schlüsselwort override und dem neuen Schlüsselwort besteht darin, dass das erstere das Überschreiben von Methoden und das spätere das Ausblenden von Methoden ausführt.
Weitere Informationen finden Sie unter den folgenden Links ...
MSDN und andere
quelle
new
Schlüsselwort ist für Verstecken. - bedeutet, dass Sie Ihre Methode zur Laufzeit verstecken. Die Ausgabe basiert auf der Basisklassenmethode.override
zum Überschreiben. - bedeutet, dass Sie Ihre abgeleitete Klassenmethode mit der Referenz der Basisklasse aufrufen. Die Ausgabe basiert auf der abgeleiteten Klassenmethode.quelle
Meine Version der Erklärung stammt aus der Verwendung von Eigenschaften , um die Unterschiede zu verstehen.
override
ist einfach genug, oder? Der zugrunde liegende Typ überschreibt den übergeordneten Typ .new
ist vielleicht die irreführende (für mich war es). Mit Eigenschaften ist es einfacher zu verstehen:Mit einem Debugger können Sie feststellen , dass
Foo foo
hat zweiGetSomething
Eigenschaften, wie sie tatsächlich hat zwei Versionen der Immobilie,Foo
‚s undBar
‘ s, und zu wissen , die man zu verwenden, c # ‚Picks‘ die Eigenschaft für den aktuellen Typen.Wenn Sie die Version der Leiste verwenden möchten, hätten Sie
Foo foo
stattdessen überschreiben oder verwenden .Bar bar
hat nur 1 , da es für völlig neues Verhalten willGetSomething
.quelle
Eine Methode nicht mit irgendetwas zu markieren bedeutet: Binden Sie diese Methode mit dem Kompilierungstyp des Objekts, nicht mit dem Laufzeittyp (statische Bindung).
Markieren einer Methode mit
virtual
Mitteln: Binden Sie diese Methode mit dem Laufzeittyp des Objekts und nicht mit dem Kompilierungszeittyp (dynamische Bindung).Das Markieren einer Basisklassenmethode
virtual
mitoverride
in einer abgeleiteten Klasse bedeutet: Dies ist die Methode, die unter Verwendung des Laufzeittyps des Objekts gebunden werden soll (dynamische Bindung).Das Markieren einer Basisklassenmethode
virtual
mitnew
in einer abgeleiteten Klasse bedeutet: Dies ist eine neue Methode, die keine Beziehung zu der Methode mit demselben Namen in der Basisklasse hat und unter Verwendung des Kompilierungszeittyps des Objekts (statische Bindung) gebunden werden sollte.Das Nichtmarkieren einer Basisklassenmethode
virtual
in der abgeleiteten Klasse bedeutet: Diese Methode wird alsnew
(statische Bindung) markiert .Das Markieren einer Methode
abstract
bedeutet: Diese Methode ist virtuell, aber ich werde keinen Body dafür deklarieren und ihre Klasse ist auch abstrakt (dynamische Bindung).quelle