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, a modyfikatory, których można użyć do zmiany sposobu dziedziczenia klas lub są dziedziczone:
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 wiele dziedziczenia nie jest dozwolone w klasach, klasy mogą implementować wiele interfejsów, co może skutecznie osiągnąć te same końce.
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 lubPrivate
, aFriend
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
instrukcja — 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ślniePublic
metody toNotOverridable
.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 instrukcjiSub
,Function
lubProperty
. Żadne inne instrukcje nie są dozwolone, a w szczególności nieEnd Sub
ma instrukcji aniEnd Function
.MustOverride
metody muszą być deklarowane wMustInherit
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ą , Payroll
i klasę pochodną , BonusPayroll
która zastępuje dziedziczona metodę PayEmployee
. Procedura, RunPayroll
, tworzy, a następnie przekazuje Payroll
obiekt i BonusPayroll
obiekt do funkcji , Pay
któ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ą zastępowane lub w tle 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 natychmiastowej klasy bazowej i jej odziedziczonych składowych. Nie można jej używać do uzyskiwania dostępuPrivate
do składowych w klasie.MyBase
jest słowem kluczowym, a nie prawdziwym obiektem.MyBase
nie można przypisać do zmiennej, przekazanej do procedur lub użytejIs
w porównaniu.Metoda, która
MyBase
kwalifikuje się, 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 przezMyBase
program w celu poprawnego skompilowania, niektóre klasy bazowe muszą zawierać metodę zgodną z nazwą i typami parametrów wyświetlanych w wywołaniu.Nie można używać
MyBase
metody do wywoływaniaMustOverride
metod klasy bazowej.MyBase
nie można użyć do zakwalifikowania się. 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, które są oznaczone tak, jakbyFriend
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
Me
przypomina metodę , ale każde wywołanie MyClass
metody i właściwości jest traktowane tak, jakby metoda lub właściwość nie były możliwe do zastąpienia. W związku z tym metoda lub właściwość nie ma wpływu na zastąpienie w klasie pochodnej.
MyClass
jest słowem kluczowym, a nie prawdziwym obiektem.MyClass
nie można przypisać do zmiennej, przekazanej do procedur lub użytejIs
w porównaniu.MyClass
odwołuje się do zawierającej klasy i jej dziedziczone elementy członkowskie.MyClass
może być używany jako kwalifikator dlaShared
członków.MyClass
nie można użyć wewnątrzShared
metody, ale można jej użyć wewnątrz metody wystąpienia, aby uzyskać dostęp do udostępnionego elementu członkowskiego klasy.MyClass
nie można używać w modułach standardowych.MyClass
Może służyć do kwalifikowania metody zdefiniowanej w klasie bazowej i nie ma implementacji metody podanej w tej klasie. Takie odwołanie ma takie samo znaczenie jakMyBase.
metoda.
Poniższy przykład porównuje i Me
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 przesłonięcia testMethod
derivedClass
MyClass
słowo kluczowe w useMyClass
parametrze nullifuje skutki zastąpienia, a kompilator rozpoznaje wywołanie do wersji klasy bazowej testMethod
klasy .