Dette er en av en miniserie som dekker forskjellene i overbelastning, skygger og overstyringer i VB.NET. Denne artikkelen dekker Overrides. Artiklene som dekker de andre er her:
-> Overbelastning
-> Skygger
Disse teknikkene kan være enormt forvirrende; det er mange kombinasjoner av disse nøkkelordene og de underliggende arvealternativene. Microsofts egen dokumentasjon begynner ikke å gjøre emnet rettferdighet, og det er mye dårlig informasjon eller utdatert informasjon på nettet. Det beste rådet for å være sikker på at programmet ditt er riktig kodet er: "Test, test og test igjen." I denne serien skal vi se på dem én om gangen med vekt på forskjellene.
Overstyrer
Det som Shadows, Overloads og Overrides alle har til felles er at de gjenbruker navnet på elementer mens de endrer det som skjer. Skygger og overbelastning kan fungere både i samme klasse eller når a klasse arver en annen klasse. Overstyring kan imidlertid bare brukes i en avledet klasse (noen ganger kalt en barneklasse) som arver fra a
grunnklasse (noen ganger kalt en foreldreklasse). Og Overrides er hammeren; den lar deg helt erstatte en metode (eller en egenskap) fra en baseklasse.I artikkelen om klasser og Shadows-nøkkelordet (se: Shadows in VB.NET) ble en funksjon lagt til for å vise at det kunne henvises til en arvet prosedyre.
Public Class ProfessionalKontakt. '... kode ikke vist... Offentlig funksjon HashTheName ( ByVal nm As String) Som streng. Returner nm. GetHashCode. Sluttfunksjon. Sluttklasse.
Koden som instantierer en klasse hentet fra denne (CodedProfessionalContact i eksempelet) kan kalle denne metoden fordi den er arvet.
I eksemplet brukte jeg VB.NET GetHashCode metode for å holde koden enkel, og dette ga et ganske ubrukelig resultat, verdien -520086483. Anta at jeg ønsket at et annet resultat skulle returneres i stedet, men,
-> Jeg kan ikke endre grunnklassen. (Kanskje alt jeg har er kompilert kode fra en leverandør.)
... og ...
-> Jeg kan ikke endre telefonkoden (kanskje det er tusen eksemplarer, og jeg kan ikke oppdatere dem.)
Hvis jeg kan oppdatere den avledede klassen, kan jeg endre resultatet som ble returnert. (For eksempel kan koden være en del av en oppdaterbar DLL.)
Det er ett problem. Fordi det er så omfattende og kraftig, må du ha tillatelse fra baseklassen til å bruke Overrides. Men godt designede kodebiblioteker gir det. (Din kodebibliotekene er alle godt designet, ikke sant?) For eksempel er funksjonen fra Microsoft som vi nettopp brukte, overstyrbar. Her er et eksempel på syntaks.
Offentlig overbrytbar funksjon GetHashCode som heltall
Så det nøkkelordet må også være tilstede i vår eksempelklasse.
Offentlig overbrytbar funksjon HashTheName ( ByVal nm As String) Som streng.
Overstyrer metoden er nå så enkelt som å gi en ny med Overrides-søkeordet. Visual Studio gir deg igjen en løpende start ved å fylle ut koden for deg med AutoComplete. Når du går inn ...
Offentlig overstyringsfunksjon HashTheName (
Visual Studio legger til resten av koden automatisk så snart du skriver inn åpnings parentesen, inkludert rettsoppgaven som bare kaller den opprinnelige funksjonen fra baseklassen. (Hvis du bare legger til noe, er det vanligvis en god ting å gjøre etter at den nye koden uansett kjøres.)
Offentlig overstyringsfunksjon HashTheName ( nm Som streng) Som streng. Returner MyBase. HashTheName (nm) Sluttfunksjon.
I dette tilfellet vil jeg imidlertid erstatte metoden med noe annet like ubrukelig bare for å illustrere hvordan det gjøres: VB.NET-funksjonen som vil reversere strengen.
Offentlig overstyringsfunksjon HashTheName ( nm Som streng) Som streng. Returner Microsoft. Visual. StrReverse (nm) Sluttfunksjon.
Nå får ringekoden et helt annet resultat. (Sammenlign med resultatet i artikkelen om Shadows.)
KontaktID: 246. Forretningsnavn: Villain Defeaters, GmbH. Hash of the BusinessName: HbmG, sretaefeD nialliV.
Du kan overstyre egenskaper også. Anta at du bestemte deg for at ContactID-verdier større enn 123 ikke ville være tillatt, og skulle være standard til 111. Du kan bare overstyre eiendommen og endre den når eiendommen er lagret:
Privat _ContactID som heltall. Offentlig tilsidesetter eiendomskontaktID som heltall. Få. Returner _ContactID. Slutt Get. Sett (byVal-verdi som heltall) Hvis verdi> 123 Da. _KontaktID = 111. Ellers. _ContactID = verdi. Slutt om. Slutt sett. Slutteiendom.
Så får du dette resultatet når en større verdi er bestått:
KontaktID: 111. Forretningsnavn: Damsel Rescuers, LTD.
For øvrig, i eksempelkoden så langt, blir heltalverdier doblet i det nye subrutine (Se artikkelen om Shadows), så et heltall på 123 blir endret til 246 og deretter endret igjen til 111.
VB.NET gir deg enda mer kontroll ved å la en baseklasse spesifikt kreve eller nekte en avledet klasse å overstyre ved hjelp av MustOverride og NotOverridable nøkkelord i baseklassen. Men begge disse brukes i ganske spesifikke tilfeller. For det første, NotOverridable.
Siden standard for en offentlig klasse er NotOverridable, hvorfor skulle du noen gang trenge å spesifisere den? Hvis du prøver det på HashTheName-funksjonen i baseklassen, får du en syntaksfeil, men teksten til feilmeldingen gir deg en anelse:
'NotOverridable' kan ikke spesifiseres for metoder som ikke tilsidesetter en annen metode.
Standard for en overstyrt metode er motsatt: Overbrytbar. Så hvis du vil at overstyring definitivt skal stoppe der, må du spesifisere NotOverridable på den metoden. I vårt eksempelkode:
Offentlig NotOredridable Overstyrer Funksjon HashTheName (...
Så hvis klassen CodedProfessionalContact er på sin side arvet ...
Offentlig klasse NotOverridableEx. Inherits CodedProfessionalContact.
... funksjonen HashTheName kan ikke overstyres i den klassen. Et element som ikke kan overstyres, kalles noen ganger et forseglet element.
En grunnleggende del av den.NET Foundation er å kreve at formålet med hver klasse er eksplisitt definert for å fjerne all usikkerhet. Et problem i tidligere OOP-språk har blitt kalt "den skjøre baseklassen." Dette skjer når en base klasse legger til en ny metode med samme navn som metodenavn i en underklasse som arver fra en base klasse. Programmereren som skrev underklassen hadde ikke tenkt å overstyre baseklassen, men det er akkurat dette som skjer uansett. Dette har vært kjent for å resultere i gråten til den sårede programmereren, "Jeg har ikke endret noe, men programmet krasjet uansett. "Hvis det er en mulighet for at en klasse vil bli oppdatert i fremtiden og skape dette problemet, erklærer du det som NotOverridable.
MustOverride brukes ofte i det som kalles en abstrakt klasse. (I C # bruker samme ting nøkkelordet Abstract!) Dette er en klasse som bare gir en mal, og du forventes å fylle den med din egen kode. Microsoft gir dette eksempelet på ett:
Vaskemaskin for offentlig bruk av arv. Sub Ny () Koden for å innlede klassen går her. Slutt sub. Offentlig MustOverride undervask. Offentlig MustOverride sub-skylling (loadSize som heltall) Offentlig MustOverride-funksjonsspinn (hastighet som heltall) så lang. Sluttklasse.
For å fortsette Microsofts eksempel, vil vaskemaskiner gjøre disse tingene (Wash, Rinse and Spin) ganske annerledes, så det er ingen fordel å definere funksjonen i baseklassen. Men det er en fordel å sørge for at enhver klasse som arver denne gjør definere dem. Løsningen: en abstrakt klasse.
Hvis du trenger enda mer forklaring om forskjellene mellom overbelastning og overstyring, utvikles et helt annet eksempel i et raskt tips: Overbelastning versus overstyring
VB.NET gir deg enda mer kontroll ved å la en baseklasse spesifikt kreve eller nekte en avledet klasse å overstyre ved hjelp av MustOverride og NotOverridable søkeord i baseklassen. Men begge disse brukes i ganske spesifikke tilfeller. For det første, NotOverridable.
Siden standard for en offentlig klasse er NotOverridable, hvorfor skulle du noen gang trenge å spesifisere den? Hvis du prøver det på HashTheName-funksjonen i baseklassen, får du en syntaksfeil, men teksten til feilmeldingen gir deg en anelse:
'NotOverridable' kan ikke spesifiseres for metoder som ikke tilsidesetter en annen metode.
Standard for en overstyrt metode er motsatt: Overbrytbar. Så hvis du vil at overstyring definitivt skal stoppe der, må du spesifisere NotOverridable på den metoden. I vårt eksempelkode:
Offentlig NotOredridable Overstyrer Funksjon HashTheName (...
Så hvis klassen CodedProfessionalContact er på sin side arvet ...
Offentlig klasse NotOverridableEx. Inherits CodedProfessionalContact.
... funksjonen HashTheName kan ikke overstyres i den klassen. Et element som ikke kan overstyres, kalles noen ganger et forseglet element.
En grunnleggende del av .NET Foundation er å kreve at formålet med hver klasse er eksplisitt definert for å fjerne all usikkerhet. Et problem i tidligere OOP-språk har blitt kalt "den skjøre baseklassen." Dette skjer når en base klasse legger til en ny metode med samme navn som metodenavn i en underklasse som arver fra en base klasse. Programmereren som skrev underklassen hadde ikke tenkt å overstyre baseklassen, men det er akkurat dette som skjer uansett. Dette har vært kjent for å resultere i gråten til den sårede programmereren, "Jeg har ikke endret noe, men programmet krasjet uansett. "Hvis det er en mulighet for at en klasse vil bli oppdatert i fremtiden og skape dette problemet, erklærer du det som NotOverridable.
MustOverride brukes ofte i det som kalles en abstrakt klasse. (I C # bruker samme ting nøkkelordet Abstract!) Dette er en klasse som bare gir en mal, og du forventes å fylle den med din egen kode. Microsoft gir dette eksempelet på ett:
Vaskemaskin for offentlig bruk av arv. Sub Ny () Koden for å innlede klassen går her. Slutt sub. Offentlig MustOverride undervask. Offentlig MustOverride sub-skylling (loadSize som heltall) Offentlig MustOverride-funksjonsspinn (hastighet som heltall) så lang. Sluttklasse.
For å fortsette Microsofts eksempel, vil vaskemaskiner gjøre disse tingene (Wash, Rinse and Spin) ganske annerledes, så det er ingen fordel å definere funksjonen i baseklassen. Men det er en fordel å sørge for at enhver klasse som arver denne gjør definere dem. Løsningen: en abstrakt klasse.
Hvis du trenger enda mer forklaring om forskjellene mellom overbelastning og overstyring, utvikles et helt annet eksempel i et raskt tips: Overbelastning versus overstyring