Základní informace o dědičnosti (Visual Basic)
InheritsPříkaz se používá k deklaraci nové třídy označované jako odvozená třída založená na stávající třídě, která se označuje jako základní třída. Odvozené třídy dědí a mohou roztáhnout, vlastnosti, metody, události, pole a konstanty definované v základní třídě. V následující části jsou popsána některá pravidla dědičnosti a modifikátory, které lze použít ke změně způsobu dědění nebo dědění tříd:
Ve výchozím nastavení jsou všechny třídy děděny, pokud nejsou označeny
NotInheritableklíčovým slovem. Třídy mohou dědit z jiných tříd v projektu nebo ze tříd v jiných sestaveních, na která projekt odkazuje.na rozdíl od jazyků, které umožňují vícenásobnou dědění, Visual Basic povoluje pouze jedinou dědičnost v třídách; To znamená, že odvozené třídy mohou mít pouze jednu základní třídu. I když v třídách není povolena vícenásobná dědičnost, třídy mohou implementovat více rozhraní, což může efektivně plnit stejné konce.
Aby nedocházelo k vystavení omezených položek v základní třídě, musí být typ přístupu odvozené třídy roven nebo větší omezující hodnotě než její základní třída.
PublicTřída například nemůže dědit třídu nebo a třídaFriendPrivateFriendnemůže děditPrivatetřídu.
Modifikátory dědičnosti
Visual Basic zavádí následující příkazy na úrovni třídy a modifikátory pro podporu dědičnosti:
Inheritspříkaz – určuje základní třídu.NotInheritableModifikátor – zabraňuje programátorům v používání třídy jako základní třídy.MustInheritModifikátor – určuje, že třída je určena pouze pro použití jako základní třída. InstanceMustInherittříd nelze vytvořit přímo; lze je vytvořit pouze jako instance základní třídy odvozené třídy. (Jiné programovací jazyky, například C++ a C#, používají pojem abstraktní třída k popsání takové třídy.)
Přepsání vlastností a metod v odvozených třídách
Ve výchozím nastavení dědí odvozená třída vlastnosti a metody ze své základní třídy. Pokud se zděděná vlastnost nebo metoda musí chovat jinak v odvozené třídě, může být přepsána. To znamená, že můžete definovat novou implementaci metody v odvozené třídě. Následující modifikátory slouží k řízení způsobu přepsání vlastností a metod:
Overridable– Umožňuje přepsat vlastnost nebo metodu ve třídě v odvozené třídě.Overrides– PřepisujeOverridablevlastnost nebo metodu definovanou v základní třídě.NotOverridable– Zabraňuje přepsání vlastnosti nebo metody v dědičné třídě. Ve výchozím nastaveníPublicjsou metodyNotOverridable.MustOverride– Vyžaduje, aby odvozená třída přepsala vlastnost nebo metodu. PřiMustOverridepoužití klíčového slova se definice metody skládá pouze zSubFunctionpříkazu, neboProperty. Nejsou povoleny žádné jiné příkazy a konkrétně neexistuje žádnýEnd SubEnd Functionpříkaz.MustOverridemetody musí být deklarovány veMustInherittřídách.
Předpokládejme, že chcete definovat třídy pro zpracování mezd. Můžete definovat obecnou Payroll třídu, která obsahuje RunPayroll metodu, která vypočítá mzdový kód pro typický týden. Pak můžete použít Payroll jako základní třídu pro konkrétnější BonusPayroll třídu, která se dá použít při distribuci prémií zaměstnanců.
BonusPayrollTřída může dědit a přepsat PayEmployee metodu definovanou v základní Payroll třídě.
Následující příklad definuje základní třídu Payroll, a odvozenou třídu, BonusPayroll která přepisuje zděděnou metodu, PayEmployee . Procedura, RunPayroll , vytvoří a poté předá Payroll objekt a BonusPayroll objekt do funkce,, Pay která provede PayEmployee metodu obou objektů.
Const BonusRate As Decimal = 1.45D
Const PayRate As Decimal = 14.75D
Class Payroll
Overridable Function PayEmployee(
ByVal HoursWorked As Decimal,
ByVal PayRate As Decimal) As Decimal
PayEmployee = HoursWorked * PayRate
End Function
End Class
Class BonusPayroll
Inherits Payroll
Overrides Function PayEmployee(
ByVal HoursWorked As Decimal,
ByVal PayRate As Decimal) As Decimal
' The following code calls the original method in the base
' class, and then modifies the returned value.
PayEmployee = MyBase.PayEmployee(HoursWorked, PayRate) * BonusRate
End Function
End Class
Sub RunPayroll()
Dim PayrollItem As Payroll = New Payroll
Dim BonusPayrollItem As New BonusPayroll
Dim HoursWorked As Decimal = 40
MsgBox("Normal pay is: " &
PayrollItem.PayEmployee(HoursWorked, PayRate))
MsgBox("Pay with bonus is: " &
BonusPayrollItem.PayEmployee(HoursWorked, PayRate))
End Sub
Klíčové slovo MyBase
MyBaseKlíčové slovo se chová jako proměnná objektu, která odkazuje na základní třídu aktuální instance třídy. MyBase se často používá pro přístup ke členům základních tříd, které jsou přepsány nebo vrženy v odvozené třídě. Konkrétně MyBase.New se používá k explicitnímu volání konstruktoru základní třídy z konstruktoru odvozené třídy.
Předpokládejme například, že navrhujete odvozenou třídu, která přepisuje metodu zděděnou ze základní třídy. Přepsaná metoda může volat metodu v základní třídě a upravit návratovou hodnotu, jak je znázorněno v následujícím fragmentu kódu:
Class DerivedClass
Inherits BaseClass
Public Overrides Function CalculateShipping(
ByVal Dist As Double,
ByVal Rate As Double) As Double
' Call the method in the base class and modify the return value.
Return MyBase.CalculateShipping(Dist, Rate) * 2
End Function
End Class
Následující seznam popisuje omezení používání MyBase :
MyBaseodkazuje na bezprostřední základní třídu a její zděděné členy. Nedá se použít pro přístup kePrivatečlenům ve třídě.MyBaseje klíčové slovo, nikoli skutečný objekt.MyBasenelze přiřadit proměnné, předávat do procedur ani použít vIsporovnání.Metoda, kterou je třeba použít,
MyBasenemusí být definována v bezprostřední základní třídě; je možné ji definovat v nepřímo zděděné základní třídě. Aby byl odkaz kvalifikován proMyBasesprávné kompilování, musí některá základní třída obsahovat metodu, která odpovídá názvu a typům parametrů, které se zobrazí ve volání.Nemůžete použít
MyBasek voláníMustOverridemetod základní třídy.MyBasenejde použít k zařazení sebe sama. Proto následující kód není platný:MyBase.MyBase.BtnOK_Click()MyBasenelze použít v modulech.MyBasenelze použít pro přístup ke členům základní třídy, které jsou označeny jako,FriendPokud je základní třída v jiném sestavení.
Další informace a další příklad naleznete v tématu How to: přístup k proměnné skryté odvozenou třídou.
Klíčové slovo MyClass
MyClassKlíčové slovo se chová jako proměnná objektu, která odkazuje na aktuální instanci třídy, jak je původně implementována. MyClass se podobá Me , ale všechny metody a volání vlastností MyClass se považují za, pokud byla metoda nebo vlastnost NotOverridable. Proto metoda nebo vlastnost není ovlivněna přepsáním v odvozené třídě.
MyClassje klíčové slovo, nikoli skutečný objekt.MyClassnelze přiřadit proměnné, předávat do procedur ani použít vIsporovnání.MyClassodkazuje na obsahující třídu a její zděděné členy.MyClassdá se použít jako kvalifikátor proSharedčleny.MyClassnelze použít uvnitřSharedmetody, ale lze ji použít uvnitř metody instance pro přístup ke sdílenému členu třídy.MyClassnelze použít ve standardních modulech.MyClasslze použít k kvalifikování metody, která je definována v základní třídě a která nemá žádnou implementaci metody uvedené v této třídě. Takový odkaz má stejný význam jakoMyBase.Metoda.
Následující příklad porovnává Me a MyClass .
Class baseClass
Public Overridable Sub testMethod()
MsgBox("Base class string")
End Sub
Public Sub useMe()
' The following call uses the calling class's method, even if
' that method is an override.
Me.testMethod()
End Sub
Public Sub useMyClass()
' The following call uses this instance's method and not any
' override.
MyClass.testMethod()
End Sub
End Class
Class derivedClass : Inherits baseClass
Public Overrides Sub testMethod()
MsgBox("Derived class string")
End Sub
End Class
Class testClasses
Sub startHere()
Dim testObj As derivedClass = New derivedClass()
' The following call displays "Derived class string".
testObj.useMe()
' The following call displays "Base class string".
testObj.useMyClass()
End Sub
End Class
I když derivedClass přepsání testMethod , MyClass klíčové slovo v useMyClass NULLIFIES účinek přepsání a kompilátor překládá volání na verzi základní třídy testMethod .