Außerkraftsetzungen in VB.NET
Overrides wird oft mit Overloads und Shadows verwechselt.
Frau, die vor einem Computer sitzt. Getty Images/Jetta-Produktionen
Dies ist Teil einer Miniserie, die die Unterschiede in Overloads, Shadows und Overrides in behandelt VB.NET . Dieser Artikel behandelt Außerkraftsetzungen. Die Artikel, die die anderen abdecken, sind hier:
-> Überlastung
-> Schatten
Diese Techniken kann sehr verwirrend sein; Es gibt viele Kombinationen dieser Schlüsselwörter und der zugrunde liegenden Vererbungsoptionen. Microsofts eigene Dokumentation wird dem Thema nicht annähernd gerecht und es gibt viele schlechte oder veraltete Informationen im Web. Der beste Rat, um sicherzustellen, dass Ihr Programm richtig codiert ist, lautet: „Testen, testen und nochmals testen“. In dieser Serie werden wir sie einzeln betrachten, wobei der Schwerpunkt auf den Unterschieden liegt.
Überschreibt
Was Shadows, Overloads und Overrides gemeinsam haben, ist, dass sie die Namen von Elementen wiederverwenden und gleichzeitig ändern, was passiert. Shadows und Overloads können sowohl innerhalb derselben Klasse als auch wenn aKlasse erbteine andere Klasse. Außerkraftsetzungen können jedoch nur in einer abgeleiteten Klasse (manchmal auch als untergeordnete Klasse bezeichnet) verwendet werden, die von a erbt Basisklasse (manchmal auch als übergeordnete Klasse bezeichnet). Und Overrides ist der Hammer; Damit können Sie eine Methode (oder eine Eigenschaft) einer Basisklasse vollständig ersetzen.
Im Artikel über Klassen und das Schlüsselwort Shadows (Siehe: Shadows in VB.NET) wurde eine Funktion hinzugefügt, um zu zeigen, dass auf eine geerbte Prozedur verwiesen werden kann.
|_+_|Der Code, der eine davon abgeleitete Klasse instanziiert (im Beispiel CodedProfessionalContact), kann diese Methode aufrufen, da sie geerbt ist.
Im Beispiel habe ich VB.NET verwendet GetHashCode Methode, um den Code einfach zu halten, und dies gab ein ziemlich nutzloses Ergebnis zurück, den Wert -520086483. Angenommen, ich möchte stattdessen ein anderes Ergebnis zurückgeben, aber
-> Ich kann die Basisklasse nicht ändern. (Vielleicht habe ich nur kompilierten Code von einem Anbieter.)
... und ...
-> Ich kann den Aufrufcode nicht ändern (Vielleicht gibt es tausend Kopien und ich kann sie nicht aktualisieren.)
Wenn ich die abgeleitete Klasse aktualisieren kann, kann ich das zurückgegebene Ergebnis ändern. (Beispielsweise könnte der Code Teil einer aktualisierbaren DLL sein.)
Es gibt ein Problem. Da es so umfassend und leistungsfähig ist, müssen Sie die Erlaubnis der Basisklasse haben, um Overrides zu verwenden. Aber gut gestaltete Codebibliotheken bieten es. ( Dein Code-Bibliotheken sind alle gut gestaltet, oder?) Zum Beispiel ist die von Microsoft bereitgestellte Funktion, die wir gerade verwendet haben, überschreibbar. Hier ist ein Beispiel für die Syntax.
Öffentliche überschreibbare Funktion GetHashCode als ganze Zahl
Dieses Schlüsselwort muss also auch in unserer Beispiel-Basisklasse vorhanden sein.
|_+_|
Überschreiben der Methode ist jetzt so einfach wie das Angeben eines neuen mit dem Schlüsselwort Overrides. Visual Studio gibt Ihnen wieder einen schnellen Start, indem es den Code mit AutoComplete für Sie ausfüllt. Wenn Du eintrittst ...
|_+_|Visual Studio fügt den Rest des Codes automatisch hinzu, sobald Sie die öffnende Klammer eingeben, einschließlich der return-Anweisung, die nur die ursprüngliche Funktion aus der Basisklasse aufruft. (Wenn Sie nur etwas hinzufügen, ist dies normalerweise ohnehin eine gute Sache, nachdem Ihr neuer Code ausgeführt wurde.)
|_+_|In diesem Fall werde ich die Methode jedoch durch etwas anderes ersetzen, das ebenso nutzlos ist, nur um zu veranschaulichen, wie es gemacht wird: Die VB.NET-Funktion, die den String umkehrt.
|_+_|Jetzt erhält der aufrufende Code ein völlig anderes Ergebnis. (Vergleiche mit dem Ergebnis im Artikel über Schatten.)
|_+_|Sie können auch Eigenschaften überschreiben. Angenommen, Sie haben entschieden, dass ContactID-Werte größer als 123 nicht zulässig sind und standardmäßig 111 betragen sollten. Sie können die Eigenschaft einfach überschreiben und ändern, wenn die Eigenschaft gespeichert wird:
|_+_|Dann erhalten Sie dieses Ergebnis, wenn ein größerer Wert übergeben wird:
|_+_|Übrigens werden im bisherigen Beispielcode ganzzahlige Werte in der New verdoppelt Subroutine (Siehe den Artikel über Schatten), also wird eine Ganzzahl von 123 in 246 und dann wieder in 111 geändert.
VB.NET gibt Ihnen sogar noch mehr Kontrolle, indem es einer Basisklasse ermöglicht, eine abgeleitete Klasse mithilfe der Schlüsselwörter „MustOverride“ und „NotOverridable“ in der Basisklasse speziell zu fordern oder zu verweigern. Aber beide werden in ziemlich speziellen Fällen verwendet. Erstens, NotOverridable.
Da der Standardwert für eine öffentliche Klasse NotOverridable ist, warum sollten Sie ihn jemals angeben müssen? Wenn Sie es mit der HashTheName-Funktion in der Basisklasse versuchen, erhalten Sie einen Syntaxfehler, aber der Text der Fehlermeldung gibt Ihnen einen Hinweis:
'NotOverridable' kann nicht für Methoden angegeben werden, die keine andere Methode überschreiben.
Der Standardwert für eine überschriebene Methode ist genau das Gegenteil: Überschreibbar. Wenn Sie also möchten, dass das Überschreiben dort definitiv aufhört, müssen Sie NotOverridable für diese Methode angeben. In unserem Beispielcode:
|_+_|Wenn dann wiederum die Klasse CodedProfessionalContact geerbt wird ...
|_+_|... die Funktion HashTheName kann in dieser Klasse nicht überschrieben werden. Ein Element, das nicht überschrieben werden kann, wird manchmal als versiegeltes Element bezeichnet.
Ein grundlegender Bestandteil von das . NET-Stiftung besteht darin, zu fordern, dass der Zweck jeder Klasse explizit definiert wird, um alle Unsicherheiten zu beseitigen. Ein Problem in früheren OOP-Sprachen wurde als fragile Basisklasse bezeichnet. Dies geschieht, wenn eine Basisklasse eine neue Methode mit demselben Namen wie ein Methodenname in einer Unterklasse hinzufügt, die von einer Basisklasse erbt. Der Programmierer, der die Unterklasse geschrieben hat, hatte nicht vor, die Basisklasse zu überschreiben, aber genau das passiert trotzdem. Dies führte bekanntermaßen zu dem Aufschrei des verwundeten Programmierers: 'Ich habe nichts geändert, aber mein Programm ist trotzdem abgestürzt.' Wenn die Möglichkeit besteht, dass eine Klasse in Zukunft aktualisiert wird und dieses Problem verursacht, deklarieren Sie sie als NotOverridable.
MustOverride wird am häufigsten in einer sogenannten abstrakten Klasse verwendet. (In C# verwendet dasselbe das Schlüsselwort Abstract!) Dies ist eine Klasse, die nur eine Vorlage bereitstellt und von Ihnen erwartet wird, dass Sie sie mit Ihrem eigenen Code füllen. Microsoft stellt dieses Beispiel bereit:
|_+_|Um das Beispiel von Microsoft fortzusetzen, werden Waschmaschinen diese Dinge (Waschen, Spülen und Schleudern) ganz anders machen, also gibt es keinen Vorteil, die Funktion in der Basisklasse zu definieren. Es ist jedoch von Vorteil, sicherzustellen, dass jede Klasse, die diese erbt, diese erbt tut definieren sie. Die Lösung: eine abstrakte Klasse.
Wenn Sie noch mehr Erläuterungen zu den Unterschieden zwischen Overloads und Overrides benötigen, wird ein völlig anderes Beispiel in einem Quick Tip entwickelt: Overloads versus Overrides
VB.NET gibt Ihnen noch mehr Kontrolle, indem es einer Basisklasse ermöglicht, das Überschreiben einer abgeleiteten Klasse mithilfe der Schlüsselwörter MustOverride und NotOverridable in der Basisklasse ausdrücklich anzufordern oder zu verweigern. Aber beide werden in ziemlich speziellen Fällen verwendet. Erstens, NotOverridable.
Da der Standardwert für eine öffentliche Klasse NotOverridable ist, warum sollten Sie ihn jemals angeben müssen? Wenn Sie es mit der HashTheName-Funktion in der Basisklasse versuchen, erhalten Sie einen Syntaxfehler, aber der Text der Fehlermeldung gibt Ihnen einen Hinweis:
'NotOverridable' kann nicht für Methoden angegeben werden, die keine andere Methode überschreiben.
Der Standardwert für eine überschriebene Methode ist genau das Gegenteil: Überschreibbar. Wenn Sie also möchten, dass das Überschreiben dort definitiv aufhört, müssen Sie NotOverridable für diese Methode angeben. In unserem Beispielcode:
|_+_|Wenn dann wiederum die Klasse CodedProfessionalContact geerbt wird ...
|_+_|... die Funktion HashTheName kann in dieser Klasse nicht überschrieben werden. Ein Element, das nicht überschrieben werden kann, wird manchmal als versiegeltes Element bezeichnet.
Ein grundlegender Teil der .NET Foundation besteht darin, zu verlangen, dass der Zweck jeder Klasse explizit definiert wird, um alle Unsicherheiten zu beseitigen. Ein Problem in früheren OOP-Sprachen wurde als fragile Basisklasse bezeichnet. Dies geschieht, wenn eine Basisklasse eine neue Methode mit demselben Namen wie ein Methodenname in einer Unterklasse hinzufügt, die von einer Basisklasse erbt. Der Programmierer, der die Unterklasse geschrieben hat, hatte nicht vor, die Basisklasse zu überschreiben, aber genau das passiert trotzdem. Dies führte bekanntermaßen zu dem Aufschrei des verwundeten Programmierers: 'Ich habe nichts geändert, aber mein Programm ist trotzdem abgestürzt.' Wenn die Möglichkeit besteht, dass eine Klasse in Zukunft aktualisiert wird und dieses Problem verursacht, deklarieren Sie sie als NotOverridable.
MustOverride wird am häufigsten in einer sogenannten abstrakten Klasse verwendet. (In C# verwendet dasselbe das Schlüsselwort Abstract!) Dies ist eine Klasse, die nur eine Vorlage bereitstellt und von Ihnen erwartet wird, dass Sie sie mit Ihrem eigenen Code füllen. Microsoft stellt dieses Beispiel bereit:
|_+_|Um das Beispiel von Microsoft fortzusetzen, werden Waschmaschinen diese Dinge (Waschen, Spülen und Schleudern) ganz anders machen, also gibt es keinen Vorteil, die Funktion in der Basisklasse zu definieren. Es ist jedoch von Vorteil, sicherzustellen, dass jede Klasse, die diese erbt, diese erbt tut definieren sie. Die Lösung: eine abstrakte Klasse.
Wenn Sie noch mehr Erläuterungen zu den Unterschieden zwischen Overloads und Overrides benötigen, wird ein völlig anderes Beispiel in einem Quick Tip entwickelt: Overloads versus Overrides