Dit is een van een miniserie die de verschillen in Overloads, Shadows en Overrides in behandelt VB.NET. Dit artikel behandelt overschrijvingen. De artikelen die de andere dekken, zijn hier:
-> Overbelastingen
-> Schaduwen
Deze technieken kan enorm verwarrend zijn; er zijn veel combinaties van deze zoekwoorden en de onderliggende overervingsopties. De eigen documentatie van Microsoft begint het onderwerp geen recht te doen en er is veel slechte of verouderde informatie op internet. Het beste advies om er zeker van te zijn dat uw programma correct is gecodeerd, is: 'Test, test en test opnieuw'. In deze serie bekijken we ze een voor een met de nadruk op de verschillen.
Overschrijft
Wat Shadows, Overloads en Overrides allemaal gemeen hebben, is dat ze de naam van elementen hergebruiken terwijl ze veranderen wat er gebeurt. Schaduwen en overbelasting kunnen zowel binnen dezelfde klasse werken als wanneer een klasse erft een andere klas. Overschrijvingen kunnen echter alleen worden gebruikt in een afgeleide klasse (soms een kindklasse genoemd) die van een
basisklasse (soms een ouderklasse genoemd). En Overrides is de hamer; het laat je een methode (of een eigenschap) volledig uit een basisklasse vervangen.In het artikel over klassen en het Shadows-sleutelwoord (Zie: Shadows in VB.NET), is een functie toegevoegd om aan te geven dat er naar een overgeërfde procedure kan worden verwezen.
Public Class ProfessionalContact. '... code niet getoond... Openbare functie HashTheName ( ByVal nm As String) As String. Geef nm terug. GetHashCode. Einde functie. Einde klasse.
De code waarmee een klasse wordt afgeleid die hiervan is afgeleid (CodedProfessionalContact in het voorbeeld) kan deze methode aanroepen omdat deze wordt overgeërfd.
In het voorbeeld heb ik de VB.NET gebruikt GetHashCode methode om de code eenvoudig te houden en dit leverde een redelijk nutteloos resultaat op, de waarde -520086483. Stel dat ik in plaats daarvan een ander resultaat wilde, maar
-> Ik kan de basisklasse niet wijzigen. (Misschien is alles wat ik heb gecompileerde code van een leverancier.)
... en ...
-> Ik kan de belcode niet wijzigen (misschien zijn er duizend exemplaren en ik kan ze niet bijwerken.)
Als ik de afgeleide klasse kan bijwerken, kan ik het geretourneerde resultaat wijzigen. (De code kan bijvoorbeeld deel uitmaken van een bij te werken DLL.)
Er is één probleem. Omdat het zo uitgebreid en krachtig is, moet u toestemming hebben van de basisklasse om Overrides te gebruiken. Maar goed ontworpen codebibliotheken bieden het. (Uw codebibliotheken zijn allemaal goed ontworpen, toch?) Bijvoorbeeld, de door Microsoft geleverde functie die we zojuist hebben gebruikt, is overschrijfbaar. Hier is een voorbeeld van de syntaxis.
Openbare overschrijfbare functie GetHashCode als geheel getal
Dus dat zoekwoord moet ook in onze voorbeeld-basisklasse aanwezig zijn.
Openbare overschrijfbare functie HashTheName ( ByVal nm As String) As String.
De methode negeren is nu net zo eenvoudig als het voorzien van een nieuw trefwoord met het trefwoord Overschrijvingen. Visual Studio geeft u opnieuw een vliegende start door de code voor u in te vullen met AutoComplete. Wanneer je binnenkomt ...
Functie voor openbare overschrijvingen HashTheName (
Visual Studio voegt de rest van de code automatisch toe zodra u het openingshaakje typt, inclusief de return-instructie die alleen de oorspronkelijke functie uit de basisklasse aanroept. (Als je gewoon iets toevoegt, is dit meestal een goede zaak om te doen nadat je nieuwe code toch is uitgevoerd.)
Functie voor openbare overschrijvingen HashTheName ( nm As String) As String. Retourneer MyBase. HashTheName (nm) Einde functie.
In dit geval ga ik de methode echter vervangen door iets anders dat even nutteloos is, gewoon om te illustreren hoe het moet: de VB.NET-functie die de string omkeert.
Functie voor openbare overschrijvingen HashTheName ( nm As String) As String. Retourneer Microsoft. VisualBasic. StrReverse (nm) Einde functie.
Nu krijgt de aanroepcode een heel ander resultaat. (Vergelijk met het resultaat in het artikel over schaduwen.)
ContactID: 246. Bedrijfsnaam: Villain Defeaters, GmbH. Hash of the BusinessName: HbmG, sretaefeD nialliV.
U kunt ook eigenschappen overschrijven. Stel dat u hebt besloten dat ContactID-waarden groter dan 123 niet zijn toegestaan en standaard 111 zouden moeten zijn. U kunt de eigenschap gewoon negeren en wijzigen wanneer de eigenschap wordt opgeslagen:
Privé _ContactID als geheel getal. Openbare overschrijft eigenschap ContactID als geheel getal. Krijgen. Retourneer _ContactID. Einde ophalen. Set (ByVal-waarde als geheel getal) Als waarde> 123 Dan. _ContactID = 111. Anders. _ContactID = waarde. Stop als. Einde set. Eigendom beëindigen.
Dan krijg je dit resultaat wanneer een grotere waarde wordt doorgegeven:
ContactID: 111. Bedrijfsnaam: Damsel Rescuers, LTD.
Trouwens, in de voorbeeldcode tot nu toe zijn de integerwaarden verdubbeld in de New subroutine (Zie het artikel over schaduwen), dus een geheel getal van 123 wordt gewijzigd in 246 en vervolgens weer gewijzigd in 111.
VB.NET geeft u nog meer controle door toe te staan dat een basisklasse een afgeleide klasse specifiek vereist of weigert om te overschrijven met behulp van de MustOverride- en NotOverridable-sleutelwoorden in de basisklasse. Maar beide worden in vrij specifieke gevallen gebruikt. Ten eerste, niet overschrijfbaar.
Aangezien de standaard voor een openbare klasse NotOverridable is, waarom zou u deze dan ooit moeten specificeren? Als je het probeert op de HashTheName-functie in de basisklasse, krijg je een syntaxisfout, maar de tekst van het foutbericht geeft je een idee:
'NotOverridable' kan niet worden opgegeven voor methoden die een andere methode niet overschrijven.
De standaard voor een overschreven methode is precies het tegenovergestelde: overschrijfbaar. Dus als u wilt dat het negeren daar zeker stopt, moet u NotOverridable opgeven voor die methode. In onze voorbeeldcode:
Openbaar niet overschrijfbaar Overschrijft Functie HashTheName (...
Als de klasse CodedProfessionalContact op zijn beurt wordt geërfd ...
Public Class NotOverridableEx. Neemt CodedProfessionalContact over.
... de functie HashTheName kan in die klasse niet worden overschreven. Een element dat niet kan worden overschreven, wordt soms een verzegeld element genoemd.
Een fundamenteel onderdeel van de .NET Foundation is te eisen dat het doel van elke klasse expliciet wordt gedefinieerd om alle onzekerheid weg te nemen. Een probleem in eerdere OOP-talen werd "de fragiele basisklasse" genoemd. Dit gebeurt wanneer een basis class voegt een nieuwe methode toe met dezelfde naam als een methodenaam in een subklasse die van een basis overneemt klasse. De programmeur die de subklasse schreef, was niet van plan de basisklasse te overschrijven, maar dit is toch precies wat er gebeurt. Het is bekend dat dit resulteert in de kreet van de gewonde programmeur: 'Ik heb niets veranderd, maar mijn programma is gecrasht hoe dan ook. "Als er een mogelijkheid is dat een klasse in de toekomst wordt bijgewerkt en dit probleem veroorzaakt, declareer dit dan als Niet overschrijfbaar.
MustOverride wordt meestal gebruikt in een zogenaamde abstracte klasse. (In C # gebruikt hetzelfde het trefwoord Abstract!) Dit is een klasse die alleen een sjabloon biedt en van u wordt verwacht dat u deze met uw eigen code vult. Microsoft geeft dit voorbeeld van een:
Openbare Must Erfklasse Wasmachine. Sub Nieuw () 'Code om de klas te instantiëren, komt hier. Einde sub. Openbare MustOverride Sub Wash. Openbare MustOverride Sub Rinse (loadSize as Integer) Public MustOverride Function Spin (snelheid als geheel getal) zo lang. Einde klasse.
Om het voorbeeld van Microsoft voort te zetten, zullen wasmachines deze dingen (wassen, spoelen en centrifugeren) heel anders doen, dus het heeft geen voordeel om de functie in de basisklasse te definiëren. Maar er is een voordeel om ervoor te zorgen dat elke klasse deze erft doet definieer ze. De oplossing: een abstracte klasse.
Als je nog meer uitleg nodig hebt over de verschillen tussen Overloads en Overrides, wordt een heel ander voorbeeld ontwikkeld in een Quick Tip: Overloads Versus Overrides
VB.NET geeft je nog meer controle door toe te staan dat een basisklasse specifiek een afgeleide klasse vereist of weigert om te overschrijven met behulp van de MustOverride- en NotOverridable-sleutelwoorden in de basisklasse. Maar beide worden in vrij specifieke gevallen gebruikt. Ten eerste, niet overschrijfbaar.
Aangezien de standaard voor een openbare klasse NotOverridable is, waarom zou u deze dan ooit moeten specificeren? Als je het probeert op de HashTheName-functie in de basisklasse, krijg je een syntaxisfout, maar de tekst van het foutbericht geeft je een idee:
'NotOverridable' kan niet worden opgegeven voor methoden die een andere methode niet overschrijven.
De standaard voor een overschreven methode is precies het tegenovergestelde: overschrijfbaar. Dus als u wilt dat het negeren daar zeker stopt, moet u NotOverridable opgeven voor die methode. In onze voorbeeldcode:
Openbaar niet overschrijfbaar Overschrijft Functie HashTheName (...
Als de klasse CodedProfessionalContact op zijn beurt wordt geërfd ...
Public Class NotOverridableEx. Neemt CodedProfessionalContact over.
... de functie HashTheName kan in die klasse niet worden overschreven. Een element dat niet kan worden overschreven, wordt soms een verzegeld element genoemd.
Een fundamenteel onderdeel van de .NET Foundation is om te eisen dat het doel van elke klasse expliciet wordt gedefinieerd om alle onzekerheid weg te nemen. Een probleem in eerdere OOP-talen werd "de fragiele basisklasse" genoemd. Dit gebeurt wanneer een basis class voegt een nieuwe methode toe met dezelfde naam als een methodenaam in een subklasse die van een basis overneemt klasse. De programmeur die de subklasse schreef, was niet van plan de basisklasse te overschrijven, maar dit is toch precies wat er gebeurt. Het is bekend dat dit resulteert in de kreet van de gewonde programmeur: 'Ik heb niets veranderd, maar mijn programma is gecrasht hoe dan ook. "Als er een mogelijkheid is dat een klasse in de toekomst wordt bijgewerkt en dit probleem veroorzaakt, declareer dit dan als Niet overschrijfbaar.
MustOverride wordt meestal gebruikt in een zogenaamde abstracte klasse. (In C # gebruikt hetzelfde het trefwoord Abstract!) Dit is een klasse die alleen een sjabloon biedt en van u wordt verwacht dat u deze met uw eigen code vult. Microsoft geeft dit voorbeeld van een:
Openbare Must Erfklasse Wasmachine. Sub Nieuw () 'Code om de klas te instantiëren, komt hier. Einde sub. Openbare MustOverride Sub Wash. Openbare MustOverride Sub Rinse (loadSize as Integer) Public MustOverride Function Spin (snelheid als geheel getal) zo lang. Einde klasse.
Om het voorbeeld van Microsoft voort te zetten, zullen wasmachines deze dingen (wassen, spoelen en centrifugeren) heel anders doen, dus het heeft geen voordeel om de functie in de basisklasse te definiëren. Maar er is een voordeel om ervoor te zorgen dat elke klasse deze erft doet definieer ze. De oplossing: een abstracte klasse.
Als je nog meer uitleg nodig hebt over de verschillen tussen Overloads en Overrides, wordt een heel ander voorbeeld ontwikkeld in een Quick Tip: Overloads Versus Overrides