Toto je jedna z minisérií, která pokrývá rozdíly v Přetížení, Stíny a Přepisy v VB.NET. Tento článek se týká přepsání. Články, které pokrývají ostatní, jsou zde:
-> Přetížení
-> Stíny
Tyto techniky může být velmi matoucí; existuje mnoho kombinací těchto klíčových slov a základních možností dědičnosti. Vlastní dokumentace společnosti Microsoft nezačne spravovat téma spravedlnosti a na webu je spousta špatných nebo zastaralých informací. Nejlepší rady, jak zajistit, aby byl váš program správně kódován, jsou: „Test, test a test znovu.“ V této sérii se na ně podíváme jeden po druhém s důrazem na rozdíly.
Přepíše
Společná věc Shadows, Overloads a Overrides je, že znovu používají jméno elementů a zároveň mění, co se stane. Stíny a přetížení mohou pracovat jak ve stejné třídě, nebo když třída dědí další třída. Přepisy však lze použít pouze v odvozené třídě (někdy nazývané podřízené třídě), která zdědí od a základní třída (někdy se nazývá rodičovská třída). A Overrides je kladivo; umožňuje zcela nahradit metodu (nebo vlastnost) ze základní třídy.
V článku o třídách a klíčovém slovu Stíny (viz: Stíny ve VB.NET) byla přidána funkce, která ukazuje, že lze odkazovat na zděděnou proceduru.
Public Class ProfessionalKontakt. '... kód není zobrazen... Veřejné funkce HashTheName ( ByVal nm jako řetězec) jako řetězec. Návrat nm. GetHashCode. Ukončit funkci. Koncová třída.
Kód, který vytvoří instanci třídy odvozené od této (CodedProfessionalContact v příkladu), může tuto metodu nazvat, protože je zděděna.
V příkladu jsem použil VB.NET GetHashCode způsob, jak udržet kód jednoduchý, a to vrátilo docela zbytečný výsledek, hodnotu -520086483. Předpokládejme, že jsem místo toho chtěl vrátit jiný výsledek, ale
-> Nemohu změnit základní třídu. (Možná mám pouze kompilovaný kód od dodavatele.)
... a ...
-> Nemohu změnit volací kód (Možná existuje tisíc kopií a nemohu je aktualizovat.)
Pokud mohu aktualizovat odvozenou třídu, mohu změnit vrácený výsledek. (Například kód může být součástí aktualizovatelné DLL.)
Je tu jeden problém. Protože je tak komplexní a výkonný, musíte mít povolení od základní třídy, abyste mohli používat Přepisy. Poskytují to však dobře navržené knihovny kódů. (Vaše Knihovny kódů jsou všechny dobře navržené, že?) Například funkce poskytovaná společností Microsoft, kterou jsme právě použili, je přetahovatelná. Zde je příklad syntaxe.
Veřejná funkce OverHable GetHashCode jako celé číslo
Toto klíčové slovo tedy musí být také v naší základní třídě.
Veřejná funkce overashable HashTheName ( ByVal nm jako řetězec) jako řetězec.
Přepsání metody je nyní stejně snadné jako poskytnout nové klíčové slovo Přepsat. Visual Studio vám opět poskytne začátek spuštěním vyplněním kódu pomocí automatického dokončování. Když zadáte ...
Funkce veřejné potlačení HashTheName (
Visual Studio přidá zbytek kódu automaticky, jakmile zadáte úvodní závorky, včetně příkazu return, který volá pouze původní funkci ze základní třídy. (Pokud něco jen přidáváte, je to obvykle dobré dělat poté, co se váš nový kód stejně spustí.)
Funkce veřejné potlačení HashTheName ( nm jako řetězec) jako řetězec. Vraťte MyBase. HashTheName (nm) Ukončit funkci.
V tomto případě však tuto metodu nahradím něčím jiným stejně zbytečným, jen abych ilustroval, jak se to dělá: Funkce VB.NET, která řetězec obrátí.
Funkce veřejné potlačení HashTheName ( nm jako řetězec) jako řetězec. Vraťte společnost Microsoft. VisualBasic. StrReverse (nm) Ukončit funkci.
Nyní má volající kód zcela odlišný výsledek. (Porovnejte s výsledkem v článku o Shadows.)
ContactID: 246. Obchodní jméno: Villain Defeaters, GmbH. Hash of BusinessName: HbmG, sretaefeD nialliV.
Můžete také přepsat vlastnosti. Předpokládejme, že jste se rozhodli, že hodnoty ContactID větší než 123 nebudou povoleny a měly by být nastaveny na 111. Můžete pouze přepsat vlastnost a změnit ji, když je vlastnost uložena:
Soukromé _KontaktID jako celé číslo. Veřejné přepíše vlastnost ContactID jako celé číslo. Dostat. Návrat _KontaktID. End Get. Set (hodnota ByVal jako celé číslo) Pokud hodnota> 123 Pak. _KontaktID = 111. Jiný. _ContactID = hodnota. Konec If. End Set. Ukončit vlastnost.
Tento výsledek pak získáte, když je předána větší hodnota:
ContactID: 111. Obchodní jméno: Damsel Rescuers, LTD.
Mimochodem, v prozatímním příkladu kódu jsou celé hodnoty zdvojnásobeny v novém podprogram (Viz článek o Shadows), takže celé číslo 123 se změní na 246 a poté se znovu změní na 111.
VB.NET vám dává ještě více kontroly tím, že umožňuje základní třídě specificky vyžadovat nebo zakázat odvozenou třídu, která má přepsat pomocí klíčových slov MustOverride a NotOverridable v základní třídě. Ale oba se používají v celkem specifických případech. Za prvé, neověřitelné.
Protože výchozí hodnota pro veřejnou třídu je NotOverridable, proč byste ji měli někdy potřebovat? Pokud to zkusíte pomocí funkce HashTheName v základní třídě, dostanete chybu syntaxe, ale text chybové zprávy vám poskytne vodítko:
'NotOverridable' nelze zadat pro metody, které nepřepisují jinou metodu.
Výchozí hodnota pro přepsanou metodu je právě naopak: Overrideable. Pokud tedy chcete, aby se rozhodování definitivně zastavilo, musíte pro tuto metodu určit NotOverridable. V našem ukázkovém kódu:
Veřejné neověřitelné Přepíše Funkce HashTheName (...
Pak, pokud je třída CodedProfessionalContact zděděna ...
Veřejná třída NotOverridableEx. Zdědí kódovanýProfesionálníKontakt.
... funkce HashTheName nemůže být přepsána v této třídě. Prvek, který nelze přepsat, se někdy nazývá zapečetěný prvek.
Základní součást .NET Foundation je vyžadovat, aby byl účel každé třídy výslovně definován, aby se odstranila veškerá nejistota. Problém v předchozích jazycích OOP byl nazýván „křehká základní třída“. To se stane, když základna třída přidá novou metodu se stejným názvem jako název metody do podtřídy, která dědí od základny třída. Programátor, který psal podtřídu, neplánoval potlačit základní třídu, ale stejně se to stane. Je známo, že to má za následek výkřik zraněného programátora: „Nic jsem nezměnil, ale můj program havaroval "Pokud existuje možnost, že třída bude v budoucnu aktualizována a vytvoří tento problém, deklarujte ji jako NotOverridable.
MustOverride se nejčastěji používá v tzv. Abstraktní třídě. (V jazyce C # používá totéž klíčové slovo Abstrakt!) Toto je třída, která poskytuje pouze šablonu a očekává se, že ji naplníte vlastním kódem. Společnost Microsoft poskytuje tento příklad:
MustInherit Class WashingMachine. Sub Nový () "Sem přichází kód, který vyvolá instanci třídy." Konec sub. Veřejné MustOverride Sub Wash. Veřejné MustOverride Sub Rinse (loadSize as Integer) Veřejná funkce MustOverride Spin (rychlost jako celé číslo) tak dlouhá. Koncová třída.
Abychom pokračovali v příkladu Microsoftu, pračky budou dělat tyto věci (Wash, Rinse a Spin) zcela odlišně, takže neexistuje žádná výhoda definování funkce v základní třídě. Výhodou však je, že každá třída, která zdědí tuto třídu ano definovat je. Řešení: abstraktní třída.
Pokud potřebujete ještě více vysvětlit rozdíly mezi přetížením a přepsáním, je v Rychlém tipu vytvořen úplně jiný příklad: Přetížení versus přepsání
VB.NET vám dává ještě větší kontrolu tím, že umožňuje základní třídě specificky vyžadovat nebo zakázat odvozenou třídu přepsat pomocí klíčových slov MustOverride a NotOverridable v základní třídě. Ale oba se používají v celkem specifických případech. Za prvé, neověřitelné.
Protože výchozí hodnota pro veřejnou třídu je NotOverridable, proč byste ji měli někdy potřebovat? Pokud to zkusíte pomocí funkce HashTheName v základní třídě, dostanete chybu syntaxe, ale text chybové zprávy vám poskytne vodítko:
'NotOverridable' nelze zadat pro metody, které nepřepisují jinou metodu.
Výchozí hodnota pro přepsanou metodu je právě naopak: Overrideable. Pokud tedy chcete, aby se rozhodování definitivně zastavilo, musíte pro tuto metodu určit NotOverridable. V našem ukázkovém kódu:
Veřejné neověřitelné Přepíše Funkce HashTheName (...
Pak, pokud je třída CodedProfessionalContact zděděna ...
Veřejná třída NotOverridableEx. Zdědí kódovanýProfesionálníKontakt.
... funkce HashTheName nemůže být přepsána v této třídě. Prvek, který nelze přepsat, se někdy nazývá zapečetěný prvek.
Zásadní součástí nadace .NET Foundation je vyžadovat, aby byl účel každé třídy výslovně definován, aby se odstranila veškerá nejistota. Problém v předchozích jazycích OOP byl nazýván „křehká základní třída“. To se stane, když základna třída přidá novou metodu se stejným názvem jako název metody do podtřídy, která dědí od základny třída. Programátor, který psal podtřídu, neplánoval potlačit základní třídu, ale stejně se to stane. Je známo, že to má za následek výkřik zraněného programátora: „Nic jsem nezměnil, ale můj program havaroval "Pokud existuje možnost, že třída bude v budoucnu aktualizována a vytvoří tento problém, deklarujte ji jako NotOverridable.
MustOverride se nejčastěji používá v tzv. Abstraktní třídě. (V jazyce C # používá totéž klíčové slovo Abstrakt!) Toto je třída, která poskytuje pouze šablonu a očekává se, že ji naplníte vlastním kódem. Společnost Microsoft poskytuje tento příklad:
MustInherit Class WashingMachine. Sub Nový () "Sem přichází kód, který vyvolá instanci třídy." Konec sub. Veřejné MustOverride Sub Wash. Veřejné MustOverride Sub Rinse (loadSize as Integer) Veřejná funkce MustOverride Spin (rychlost jako celé číslo) tak dlouhá. Koncová třída.
Abychom pokračovali v příkladu Microsoftu, pračky budou dělat tyto věci (Wash, Rinse a Spin) zcela odlišně, takže neexistuje žádná výhoda definování funkce v základní třídě. Výhodou však je, že každá třída, která zdědí tuto třídu ano definovat je. Řešení: abstraktní třída.
Pokud potřebujete ještě více vysvětlit rozdíly mezi přetížením a přepsáním, je v Rychlém tipu vytvořen úplně jiný příklad: Přetížení versus přepsání