Dies ist Teil einer Miniserie, die die Unterschiede bei Überladungen, Schatten und Überschreibungen in abdeckt VB.NET. Dieser Artikel behandelt Überschreibungen. Die Artikel, die die anderen behandeln, sind hier:
-> Überlastungen
-> 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 gerecht und es gibt viele schlechte oder veraltete Informationen im Web. Der beste Rat, um sicherzustellen, dass Ihr Programm korrekt codiert ist, lautet "Testen, testen und erneut testen". In dieser Serie werden wir sie einzeln betrachten, wobei die Unterschiede im Vordergrund stehen.
Überschreibungen
Gemeinsam ist Shadows, Overloads und Overrides, dass sie den Namen von Elementen wiederverwenden, während sie ändern, was passiert. Schatten und Überladungen können beide innerhalb derselben Klasse oder wenn a Klasse erbt eine andere Klasse. Überschreibungen können jedoch nur in einer abgeleiteten Klasse (manchmal auch als untergeordnete Klasse bezeichnet) verwendet werden, die von a erbt
Basisklasse (manchmal auch als Elternklasse bezeichnet). Und Overrides ist der Hammer; Damit können Sie eine Methode (oder eine Eigenschaft) aus einer Basisklasse vollständig ersetzen.In dem 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.
Public Class ProfessionalContact. '... Code nicht angezeigt... Öffentliche Funktion HashTheName ( ByVal nm As String) As String. Rückgabe nm. GetHashCode. Endfunktion. Klasse beenden.
Der Code, der eine von dieser abgeleitete Klasse instanziiert (im Beispiel CodedProfessionalContact), kann diese Methode aufrufen, da sie vererbt wurde.
Im Beispiel habe ich das VB.NET verwendet GetHashCode Methode, um den Code einfach zu halten, und dies ergab ein ziemlich nutzloses Ergebnis, den Wert -520086483. Angenommen, ich wollte stattdessen ein anderes Ergebnis zurückgeben, aber
-> Ich kann die Basisklasse nicht ändern. (Vielleicht habe ich nur Code von einem Anbieter kompiliert.)
... und ...
-> Ich kann den Aufrufcode nicht ändern (Vielleicht gibt es tausend Exemplare und ich kann sie nicht aktualisieren.)
Wenn ich die abgeleitete Klasse aktualisieren kann, kann ich das zurückgegebene Ergebnis ändern. (Der Code könnte beispielsweise Teil einer aktualisierbaren DLL sein.)
Es gibt ein Problem. Da es so umfassend und leistungsstark ist, müssen Sie über die Berechtigung der Basisklasse verfügen, um Overrides verwenden zu können. Aber gut gestaltete Codebibliotheken bieten es. (Ihre Codebibliotheken 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 As Integer
Dieses Schlüsselwort muss also auch in unserer Beispielbasisklasse vorhanden sein.
Öffentliche überschreibbare Funktion HashTheName ( ByVal nm As String) As String.
Methode überschreiben ist jetzt so einfach wie das Bereitstellen eines neuen mit dem Schlüsselwort Overrides. Visual Studio bietet Ihnen erneut einen Start, indem Sie den Code mit AutoComplete für Sie eingeben. Wenn Du eintrittst ...
Öffentliche Überschreibungsfunktion HashTheName (
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 eine gute Sache, nachdem Ihr neuer Code trotzdem ausgeführt wurde.)
Öffentliche Überschreibungsfunktion HashTheName ( nm als String) als String. MyBase zurückgeben. HashTheName (nm) Endfunktion.
In diesem Fall werde ich die Methode jedoch durch etwas anderes ersetzen, das ebenfalls nutzlos ist, um zu veranschaulichen, wie es gemacht wird: Die VB.NET-Funktion, die die Zeichenfolge umkehrt.
Öffentliche Überschreibungsfunktion HashTheName ( nm als String) als String. Geben Sie Microsoft zurück. VisualBasic. StrReverse (nm) Endfunktion.
Jetzt erhält der aufrufende Code ein völlig anderes Ergebnis. (Vergleiche mit dem Ergebnis im Artikel über Schatten.)
Kontakt-ID: 246. Firmenname: Villain Defeaters, GmbH. Hash des Geschäftsnamens: HbmG, sretaefeD nialliV.
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 verwenden sollen. Sie können die Eigenschaft einfach überschreiben und beim Speichern der Eigenschaft ändern:
Private _ContactID As Integer. Public überschreibt die Eigenschaft ContactID als Ganzzahl. Bekommen. _ContactID zurückgeben. End Get. Set (ByVal-Wert als Ganzzahl) Wenn Wert> 123 Dann. _ContactID = 111. Sonst. _ContactID = Wert. End If. End Set. Endeigenschaft.
Dann erhalten Sie dieses Ergebnis, wenn ein größerer Wert übergeben wird:
Kontakt-ID: 111. Geschäftsname: Damsel Rescuers, LTD.
Übrigens werden im bisherigen Beispielcode ganzzahlige Werte im Neuen verdoppelt Subroutine (Siehe den Artikel über Schatten), daher wird eine Ganzzahl von 123 in 246 und dann erneut in 111 geändert.
VB.NET bietet Ihnen noch mehr Kontrolle, indem es einer Basisklasse ermöglicht, eine abgeleitete Klasse mithilfe der Schlüsselwörter MustOverride und NotOverridable in der Basisklasse spezifisch zu überschreiben oder zu verweigern. Beide werden jedoch in ziemlich spezifischen Fällen verwendet. Erstens NotOverridable.
Da die Standardeinstellung für eine öffentliche Klasse NotOverridable ist, warum sollten Sie sie jemals angeben müssen? Wenn Sie es mit der HashTheName-Funktion in der Basisklasse versuchen, wird ein Syntaxfehler angezeigt, aber der Text der Fehlermeldung gibt Ihnen einen Hinweis:
'NotOverridable' kann nicht für Methoden angegeben werden, die keine andere Methode überschreiben.
Die Standardeinstellung 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:
Public NotOverridable Überschreibungen Funktion HashTheName (...
Wenn dann die Klasse CodedProfessionalContact wiederum geerbt wird ...
Öffentliche Klasse NotOverridableEx. Erbt CodedProfessionalContact.
... 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 von das .NET Foundation ist 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 passiert bei einer Basis Klasse fügt eine neue Methode mit demselben Namen wie ein Methodenname in einer Unterklasse hinzu, die von einer Basis erbt Klasse. Der Programmierer, der die Unterklasse schreibt, hatte nicht vor, die Basisklasse zu überschreiben, aber genau das passiert trotzdem. Es ist bekannt, dass dies zu dem Schrei des verwundeten Programmierers führt: "Ich habe nichts geändert, aber mein Programm ist abgestürzt sowieso. "Wenn die Möglichkeit besteht, dass eine Klasse in Zukunft aktualisiert wird und dieses Problem verursacht, deklarieren Sie es als NotOverridable.
MustOverride wird am häufigsten in einer sogenannten abstrakten Klasse verwendet. (In C # wird das Schlüsselwort Abstract verwendet!) Dies ist eine Klasse, die nur eine Vorlage bereitstellt und von der erwartet wird, dass Sie sie mit Ihrem eigenen Code füllen. Microsoft bietet dieses Beispiel:
Öffentliche MustInherit Class WashingMachine. Sub New () 'Code zum Instanziieren der Klasse geht hier. End Sub. Public MustOverride Sub Wash. Public MustOverride Sub Rinse (loadSize as Integer) Öffentliche MustOverride-Funktion Spin (Geschwindigkeit als Ganzzahl) so lange. Klasse beenden.
Um das Beispiel von Microsoft fortzusetzen, werden Waschmaschinen diese Dinge (Waschen, Spülen und Schleudern) ganz anders ausführen, sodass es keinen Vorteil hat, die Funktion in der Basisklasse zu definieren. Es ist jedoch von Vorteil, sicherzustellen, dass jede Klasse diese erbt tut definiere sie. Die Lösung: eine abstrakte Klasse.
Wenn Sie noch mehr Erklärungen zu den Unterschieden zwischen Überlastungen und Überschreibungen benötigen, finden Sie in einem Quick-Tipp ein völlig anderes Beispiel: Überlastungen versus Überschreibungen
VB.NET bietet Ihnen noch mehr Kontrolle, indem es einer Basisklasse ermöglicht, eine abgeleitete Klasse mithilfe der Schlüsselwörter MustOverride und NotOverridable in der Basisklasse spezifisch zu überschreiben oder zu verweigern. Beide werden jedoch in ziemlich spezifischen Fällen verwendet. Erstens NotOverridable.
Da die Standardeinstellung für eine öffentliche Klasse NotOverridable ist, warum sollten Sie sie jemals angeben müssen? Wenn Sie es mit der HashTheName-Funktion in der Basisklasse versuchen, wird ein Syntaxfehler angezeigt, aber der Text der Fehlermeldung gibt Ihnen einen Hinweis:
'NotOverridable' kann nicht für Methoden angegeben werden, die keine andere Methode überschreiben.
Die Standardeinstellung 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:
Public NotOverridable Überschreibungen Funktion HashTheName (...
Wenn dann die Klasse CodedProfessionalContact wiederum geerbt wird ...
Öffentliche Klasse NotOverridableEx. Erbt CodedProfessionalContact.
... Die Funktion HashTheName kann in dieser Klasse nicht überschrieben werden. Ein Element, das nicht überschrieben werden kann, wird manchmal als versiegeltes Element bezeichnet.
Ein wesentlicher Bestandteil 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 passiert bei einer Basis Klasse fügt eine neue Methode mit demselben Namen wie ein Methodenname in einer Unterklasse hinzu, die von einer Basis erbt Klasse. Der Programmierer, der die Unterklasse schreibt, hatte nicht vor, die Basisklasse zu überschreiben, aber genau das passiert trotzdem. Es ist bekannt, dass dies zu dem Schrei des verwundeten Programmierers führt: "Ich habe nichts geändert, aber mein Programm ist abgestürzt sowieso. "Wenn die Möglichkeit besteht, dass eine Klasse in Zukunft aktualisiert wird und dieses Problem verursacht, deklarieren Sie es als NotOverridable.
MustOverride wird am häufigsten in einer sogenannten abstrakten Klasse verwendet. (In C # wird das Schlüsselwort Abstract verwendet!) Dies ist eine Klasse, die nur eine Vorlage bereitstellt und von der erwartet wird, dass Sie sie mit Ihrem eigenen Code füllen. Microsoft bietet dieses Beispiel:
Öffentliche MustInherit Class WashingMachine. Sub New () 'Code zum Instanziieren der Klasse geht hier. End Sub. Public MustOverride Sub Wash. Public MustOverride Sub Rinse (loadSize as Integer) Öffentliche MustOverride-Funktion Spin (Geschwindigkeit als Ganzzahl) so lange. Klasse beenden.
Um das Beispiel von Microsoft fortzusetzen, werden Waschmaschinen diese Dinge (Waschen, Spülen und Schleudern) ganz anders ausführen, sodass es keinen Vorteil hat, die Funktion in der Basisklasse zu definieren. Es ist jedoch von Vorteil, sicherzustellen, dass jede Klasse diese erbt tut definiere sie. Die Lösung: eine abstrakte Klasse.
Wenn Sie noch mehr Erklärungen zu den Unterschieden zwischen Überlastungen und Überschreibungen benötigen, finden Sie in einem Quick-Tipp ein völlig anderes Beispiel: Überlastungen versus Überschreibungen