Základní informace o dědičnosti (Visual Basic)

Příkaz Inherits se používá k deklaraci nové třídy, která se nazývá odvozená třída na základě existující třídy, označované jako základní třída. Odvozené třídy dědí a mohou rozšířit vlastnosti, metody, události, pole a konstanty definované v základní třídě. Následující část popisuje některá pravidla dědičnosti a modifikátory, které můžete použít ke změně způsobu, jakým třídy dědí nebo jsou zděděny:

  • Ve výchozím nastavení jsou všechny třídy zděděné, pokud nejsou označené klíčovým slovem NotInheritable . Třídy mohou dědit z jiných tříd v projektu nebo z tříd v jiných sestaveních, která projekt odkazuje.

  • Na rozdíl od jazyků, které umožňují více dědičnosti, jazyk Visual Basic umožňuje pouze jednu dědičnost ve třídách; to znamená, že odvozené třídy mohou mít pouze jednu základní třídu. I když není ve třídách povoleno více dědičnosti, třídy mohou implementovat více rozhraní, což může efektivně dosáhnout stejných konců.

  • Chcete-li zabránit zveřejnění omezených položek v základní třídě, musí být typ přístupu odvozené třídy roven nebo více omezující než její základní třída. Třída nemůže například Public dědit Friend třídu nebo Private třídu a Friend třída nemůže dědit Private třídu.

Modifikátory dědičnosti

Visual Basic zavádí následující příkazy a modifikátory na úrovni třídy pro podporu dědičnosti:

  • Inherits statement — Určuje základní třídu.

  • NotInheritable modifikátor — Zabraňuje programátorům v používání třídy jako základní třídy.

  • MustInherit modifikátor — Určuje, že třída je určena pouze jako základní třída. MustInherit Instance tří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í k popisu takové třídy abstraktní třídu .)

Přepsání vlastností a metod v odvozených třídách

Odvozená třída ve výchozím nastavení dědí vlastnosti a metody ze své základní třídy. Pokud se zděděná vlastnost nebo metoda musí chovat odlišně v odvozené třídě, lze ji přepsat. To znamená, že můžete definovat novou implementaci metody v odvozené třídě. K řízení způsobu přepsání vlastností a metod se používají následující modifikátory:

  • Overridable — Umožňuje přepsání vlastnosti nebo metody ve třídě v odvozené třídě.

  • Overrides — Přepíše vlastnost nebo metodu Overridable definovanou v základní třídě.

  • NotOverridable — Zabraňuje přepsání vlastnosti nebo metody v zděděné třídě. Ve výchozím nastavení Public jsou NotOverridablemetody .

  • MustOverride — Vyžaduje, aby odvozená třída přepsala vlastnost nebo metodu. Při použití klíčového MustOverride slova se definice metody skládá pouze Subz , Function, nebo Property příkazu. Nejsou povoleny žádné další příkazy a konkrétně neexistují žádné End Sub ani End Function příkazy. MustOverride metody musí být deklarovány ve MustInherit třídách.

Předpokládejme, že chcete definovat třídy pro zpracování mzdy. Můžete definovat obecnou Payroll třídu, která obsahuje metodu RunPayroll , která počítá mzdy za typický týden. Pak byste mohli použít Payroll jako základní třídu pro specializovanější BonusPayroll třídu, která by se dala použít při distribuci bonusů zaměstnanců.

Třída BonusPayroll může dědit a přepsat metodu definovanou PayEmployee v základní Payroll třídě.

Následující příklad definuje základní třídu Payroll, a odvozenou třídu, BonusPayrollkterá přepíše zděděnou metodu, PayEmployee. Procedura , RunPayrollvytvoří a poté předá Payroll objekt a BonusPayroll objekt funkci, Paykterá spustí metodu PayEmployee 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

Klíčové MyBase 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 k členům základní třídy, které jsou přepsány nebo stínovány v odvozené třídě. Konkrétně MyBase.New se používá k explicitní volání konstruktoru základní třídy z konstruktoru odvozené třídy.

Předpokládejme například, že navrhujete odvozenou třídu, která přepíše metodu zděděnou ze základní třídy. Přepsáná 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žití MyBase:

  • MyBase odkazuje na okamžitou základní třídu a její zděděné členy. Nelze jej použít pro přístup ke Private členům ve třídě.

  • MyBase je klíčové slovo, nikoli skutečný objekt. MyBase nelze přiřadit proměnné, předat procedury nebo použít v Is porovnání.

  • Metoda, která MyBase kvalifikuje, nemusí být definována v bezprostřední základní třídě; může být definována nepřímo zděděnou základní třídou. Aby se odkaz mohl MyBase správně zkompilovat, musí některá základní třída obsahovat metodu odpovídající názvu a typům parametrů, které se zobrazí ve volání.

  • Nelze použít MyBase k volání MustOverride metod základní třídy.

  • MyBase nelze použít k získání kvalifikace. Proto následující kód není platný:

    MyBase.MyBase.BtnOK_Click()

  • MyBase nelze použít v modulech.

  • MyBase nelze použít pro přístup k členům základní třídy, které jsou označeny, jako Friend by základní třída byla v jiném sestavení.

Další informace a další příklad naleznete v tématu Postupy: Přístup k proměnné skryté odvozenou třídou.

Klíčové slovo MyClass

Klíčové MyClass slovo se chová jako proměnná objektu, která odkazuje na aktuální instanci třídy, jak byla původně implementována. MyClassMepřipomíná , ale každá metoda a volání MyClass vlastnosti je považováno za to, jako by metoda nebo vlastnost NotOverridable. Proto není metoda nebo vlastnost ovlivněna přepsáním v odvozené třídě.

  • MyClass je klíčové slovo, nikoli skutečný objekt. MyClass nelze přiřadit proměnné, předat procedury nebo použít v Is porovnání.

  • MyClass odkazuje na třídu obsahující a její zděděné členy.

  • MyClass lze použít jako kvalifikátor pro Shared členy.

  • MyClass nelze použít uvnitř Shared metody, ale lze ji použít uvnitř metody instance pro přístup ke sdílenému členu třídy.

  • MyClass nelze použít ve standardních modulech.

  • MyClass lze použít k kvalifikaci metody, která je definována v základní třídě a která nemá žádnou implementaci metody poskytnuté v této třídě. Takový odkaz má stejný význam jako MyBase.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řepíše testMethod, MyClass klíčové slovo v useMyClass nullifuje účinky přepsání, a kompilátor přeloží volání na základní třídu verze testMethod.

Viz také