Udostępnij za pośrednictwem


Podstawowe informacje o dziedziczeniu (Visual Basic)

Instrukcja Inherits służy do deklarowania nowej klasy nazywanej klasą pochodną na podstawie istniejącej klasy znanej jako klasa bazowa. Klasy pochodne dziedziczą i mogą rozszerzać właściwości, metody, zdarzenia, pola i stałe zdefiniowane w klasie bazowej. W poniższej sekcji opisano niektóre reguły dziedziczenia oraz modyfikatory, których można użyć do zmiany sposobu, w jaki klasy dziedziczą lub są dziedziczone po nich.

  • Domyślnie wszystkie klasy są dziedziczone, chyba że są oznaczone NotInheritable słowem kluczowym. Klasy mogą dziedziczyć z innych klas w projekcie lub z klas w innych zestawach, do których odwołuje się projekt.

  • W przeciwieństwie do języków, które zezwalają na wiele dziedziczenia, Visual Basic zezwala tylko na pojedyncze dziedziczenie w klasach; oznacza to, że klasy pochodne mogą mieć tylko jedną klasę bazową. Mimo że wielokrotne dziedziczenie nie jest dozwolone w klasach, klasy mogą implementować wiele interfejsów, co skutecznie umożliwia osiągnięcie tego samego celu.

  • Aby zapobiec uwidacznianiu elementów z ograniczeniami w klasie bazowej, typ dostępu klasy pochodnej musi być równy lub bardziej restrykcyjny niż jej klasa bazowa. Na przykład Public klasa nie może dziedziczyć Friend klasy lub Private , a Friend klasa nie może dziedziczyć Private klasy.

Modyfikatory dziedziczenia

W języku Visual Basic wprowadzono następujące instrukcje i modyfikatory na poziomie klasy w celu obsługi dziedziczenia:

  • Inherits deklaracja — określa klasę bazową.

  • NotInheritable modyfikator — uniemożliwia programistom używanie klasy jako klasy bazowej.

  • MustInherit modyfikator — określa, że klasa jest przeznaczona tylko do użycia jako klasa bazowa. MustInherit Nie można utworzyć bezpośrednio wystąpień klas. Można je utworzyć tylko jako wystąpienia klasy bazowej klasy pochodnej. (Inne języki programowania, takie jak C++ i C#, używają terminu klasa abstrakcyjna do opisania takiej klasy).

Zastępowanie właściwości i metod w klasach pochodnych

Domyślnie klasa pochodna dziedziczy właściwości i metody z klasy bazowej. Jeśli dziedziczona właściwość lub metoda musi zachowywać się inaczej w klasie pochodnej, może zostać zastąpiona. Oznacza to, że można zdefiniować nową implementację metody w klasie pochodnej. Następujące modyfikatory służą do kontrolowania sposobu zastępowania właściwości i metod:

  • Overridable — Umożliwia zastąpienie właściwości lub metody w klasie w klasie pochodnej.

  • Overrides — zastępuje właściwość lub metodę zdefiniowaną Overridable w klasie bazowej.

  • NotOverridable — uniemożliwia zastąpienie właściwości lub metody w klasie dziedziczonej. Domyślnie Public metody to NotOverridable.

  • MustOverride — Wymaga, aby klasa pochodna zastąpiła właściwość lub metodę. MustOverride Gdy słowo kluczowe jest używane, definicja metody składa się tylko z instrukcji Sub, Functionlub Property . Żadne inne instrukcje nie są dozwolone, a w szczególności nie ma żadnej instrukcji End Sub ani End Function. MustOverride metody muszą być deklarowane w MustInherit klasach.

Załóżmy, że chcesz zdefiniować klasy do obsługi listy płac. Można zdefiniować klasę ogólną Payroll zawierającą metodę RunPayroll , która oblicza listę płac dla typowego tygodnia. Następnie można użyć Payroll jako klasy bazowej dla bardziej wyspecjalizowanej BonusPayroll klasy, która może być używana podczas dystrybucji premii pracowników.

Klasa BonusPayroll może dziedziczyć i zastępować metodę zdefiniowaną PayEmployee w klasie bazowej Payroll .

W poniższym przykładzie zdefiniowano klasę bazową , Payrolli klasę pochodną , BonusPayrollktóra zastępuje dziedziczona metodę PayEmployee. Procedura, RunPayroll, tworzy, a następnie przekazuje Payroll obiekt i BonusPayroll obiekt do funkcji , Payktóra wykonuje PayEmployee metodę obu obiektów.

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

Słowo kluczowe MyBase

Słowo MyBase kluczowe zachowuje się jak zmienna obiektu, która odwołuje się do klasy bazowej bieżącego wystąpienia klasy. MyBase jest często używany do uzyskiwania dostępu do składowych klasy bazowej, które są przesłonięte lub ukryte w klasie pochodnej. W szczególności MyBase.New służy do jawnego wywoływania konstruktora klasy bazowej z konstruktora klasy pochodnej.

Załóżmy na przykład, że projektujesz klasę pochodną, która zastępuje metodę dziedziczona z klasy bazowej. Metoda zastąpiona może wywołać metodę w klasie bazowej i zmodyfikować wartość zwracaną, jak pokazano w poniższym fragcie kodu:

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

Poniższa lista zawiera opis ograniczeń dotyczących używania programu MyBase:

  • MyBase odwołuje się do bezpośredniej klasy bazowej i jej odziedziczonych członków. Nie można jej używać do uzyskiwania dostępu do składowych Private w klasie.

  • MyBase jest słowem kluczowym, a nie prawdziwym obiektem. MyBase nie można przypisać do zmiennej, przekazać do procedur ani użyć Is w porównaniu.

  • Metoda, do której odnosi się MyBase, nie musi być zdefiniowana w bezpośredniej klasie bazowej; zamiast tego może być zdefiniowana w pośrednio dziedziczonej klasie bazowej. Aby odwołanie kwalifikowane przez MyBase mogło poprawnie się skompilować, jakaś klasa bazowa musi zawierać metodę o zgodnej nazwie i typach parametrów wyświetlanych w wywołaniu.

  • Nie można używać MyBase do wywoływania metod klasy bazowej MustOverride.

  • MyBase nie można użyć do definiowania siebie. W związku z tym następujący kod jest nieprawidłowy:

    MyBase.MyBase.BtnOK_Click()

  • MyBase nie można używać w modułach.

  • MyBase nie można używać do uzyskiwania dostępu do składowych klasy bazowej oznaczonych jako Friend, jeśli klasa bazowa znajduje się w innym zestawie.

Aby uzyskać więcej informacji i inny przykład, zobacz Jak uzyskać dostęp do zmiennej ukrytej przez klasę pochodną.

Słowo kluczowe MyClass

Słowo MyClass kluczowe zachowuje się jak zmienna obiektu, która odwołuje się do bieżącego wystąpienia klasy jako pierwotnie zaimplementowanej. MyClass przypomina Me, ale każde wywołanie metody lub właściwości na MyClass jest traktowane tak, jakby metoda lub właściwość były oznaczone jako NotOverridable. W związku z tym metoda lub właściwość nie jest dotknięta zastępowaniem w klasie pochodnej.

  • MyClass jest słowem kluczowym, a nie prawdziwym obiektem. MyClass nie można przypisać do zmiennej, przekazać do procedur ani użyć Is w porównaniu.

  • MyClass odwołuje się do zawierającej ją klasy i jej dziedziczonych elementów członkowskich.

  • MyClass może być używany jako kwalifikator dla Shared elementów.

  • MyClass nie można użyć wewnątrz metody Shared, ale można go użyć wewnątrz metody instancji, aby uzyskać dostęp do współdzielonego członka klasy.

  • MyClass nie można używać w modułach standardowych.

  • MyClass może być używany do kwalifikowania metody zdefiniowanej w klasie bazowej, która nie zawiera implementacji tej metody. Takie odwołanie ma takie samo znaczenie jak MyBase.metoda.

Poniższy przykład porównuje Me oraz 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

Mimo że derivedClass przesłania testMethod, słowo kluczowe MyClass w useMyClass unieważnia skutki przesłaniania, a kompilator rozpoznaje wywołanie wersji klasy bazowej testMethod.

Zobacz też