Grundlagen der Vererbung (Visual Basic)
Die Inherits
-Anweisung wird verwendet, um eine neue Klasse zu deklarieren, die als abgeleitete Klasse bezeichnet wird, basierend auf einer vorhandenen Klasse, die als Basisklasse bezeichnet wird. Abgeleitete Klassen erben die in der Basisklasse definierten Eigenschaften, Methoden, Ereignisse, Felder und Konstanten und können diese erweitern. Im folgenden Abschnitt werden einige der Regeln für die Vererbung und die Modifizierer beschrieben, mit denen Sie die Art und Weise ändern können, wie Klassen erben oder geerbt werden:
Standardmäßig können alle Klassen geerbt werden, es sei denn, sie sind mit dem Schlüsselwort
NotInheritable
gekennzeichnet. Klassen können von anderen Klassen in Ihrem Projekt oder von Klassen in anderen Assemblys erben, auf die Ihr Projekt verweist.Im Gegensatz zu Sprachen, die mehrfache Vererbung zulassen, lässt Visual Basic nur einzelne Vererbung in Klassen zu, d. h. abgeleitete Klassen können nur über eine Basisklasse verfügen. Obwohl die mehrfache Vererbung in Klassen nicht zulässig ist, können Klassen mehrere Schnittstellen implementieren, wodurch effektiv dieselben Ziele erreicht werden können.
Um das Verfügbarmachen eingeschränkter Elemente in einer Basisklasse zu verhindern, muss der Zugriffstyp einer abgeleiteten Klasse gleich seiner Basisklasse oder restriktiver sein. Beispielsweise kann eine
Public
-Klasse keineFriend
- oderPrivate
-Klasse erben, und eineFriend
-Klasse kann keinePrivate
-Klasse erben.
Vererbungsmodifizierer
Visual Basic führt die folgenden Anweisungen und Modifizierer auf Klassenebene ein, um Vererbung zu unterstützen:
Inherits
-Anweisung: Gibt die Basisklasse an.NotInheritable
-Modifizierer: Verhindert, dass Programmierer die Klasse als Basisklasse verwenden.MustInherit
-Modifizierer: Gibt an, dass die Klasse nur als Basisklasse verwendet werden soll. Instanzen vonMustInherit
-Klassen können nicht direkt erstellt werden. Sie können nur als Basisklasseninstanzen einer abgeleiteten Klasse erstellt werden. (Andere Programmiersprachen, z. B. C++ und C#, verwenden den Begriff abstrakte Klasse, um eine solche Klasse zu beschreiben.)
Überschreiben von Eigenschaften und Methoden in abgeleiteten Klassen
Standardmäßig erbt eine abgeleitete Klasse Eigenschaften und Methoden von ihrer Basisklasse. Wenn sich eine geerbte Eigenschaft oder Methode in der abgeleiteten Klasse anders verhalten muss, kann sie überschrieben (außer Kraft gesetzt) werden. Das heißt, Sie können eine neue Implementierung der Methode in der abgeleiteten Klasse definieren. Mit folgenden Modifizierern steuern Sie das Überschreiben von Eigenschaften und Methoden:
Overridable
: Ermöglicht das Überschreiben einer Eigenschaft oder Methode in einer Klasse in einer abgeleiteten Klasse.Overrides
: Überschreibt eine in der Basisklasse definierteOverridable
Eigenschaft oder Methode.NotOverridable
: Verhindert, dass eine Eigenschaft oder Methode in einer erbenden Klasse überschrieben wird. Standardmäßig sindPublic
-MethodenNotOverridable
.MustOverride
: Erfordert, dass eine abgeleitete Klasse die Eigenschaft oder Methode überschreibt. Wenn SchlüsselwortMustOverride
verwendet wird, besteht die Methodendefinition nur aus derSub
-,Function
oderProperty
-Anweisung. Es sind keine anderen Anweisungen zulässig, und insbesondere gibt es keineEnd Sub
- oderEnd Function
-Anweisung.MustOverride
-Methoden müssen inMustInherit
-Klassen deklariert werden.
Angenommen, Sie möchten Klassen definieren, um die Gehaltsabrechnung zu verarbeiten. Sie können eine generische Payroll
-Klasse definieren, die eine RunPayroll
-Methode enthält, die die Gehaltsabrechnung für eine typische Woche berechnet. Sie könnten dann Payroll
als Basisklasse für eine spezialisiertere BonusPayroll
-Klasse verwenden, die beim Verteilen von Mitarbeiterboni verwendet werden könnte.
Die BonusPayroll
-Klasse kann die in der Basisklasse Payroll
definierte PayEmployee
-Methode erben und überschreiben.
Im folgenden Beispiel wird eine Basisklasse und Payroll
eine abgeleitete Klasse definiert, BonusPayroll
die eine geerbte Methode PayEmployee
überschreibt. Eine RunPayroll
-Prozedur erstellt ein Payroll
-Objekt und ein BonusPayroll
-Objekt, die sie dann eine Pay
-Funktion übergibt, die die PayEmployee
-Methode beider Objekte ausführt.
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
Das Schlüsselwort „MyBase“
Das Schlüsselwort MyBase
verhält sich wie eine Objektvariable, die auf die Basisklasse der aktuellen Instanz einer Klasse verweist. MyBase
wird häufig für den Zugriff auf Basisklassenmember verwendet, die in einer abgeleiteten Klasse überschrieben oder für die ein Shadowing durchgeführt wird. MyBase.New
wird insbesondere verwendet, um explizit einen Basisklassenkonstruktor aus einem abgeleiteten Klassenkonstruktor aufzurufen.
Angenommen, Sie entwerfen beispielsweise eine abgeleitete Klasse, die eine Methode überschreibt, die von der Basisklasse geerbt wird. Die überschriebene Methode kann die Methode in der Basisklasse aufrufen und den Rückgabewert ändern, wie im folgenden Codefragment gezeigt:
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
In der folgenden Liste werden Einschränkungen für die Verwendung von MyBase
beschrieben:
MyBase
bezieht sich auf die unmittelbare Basisklasse und ihre geerbten Member. Es kann nicht verwendet werden, um aufPrivate
Member in der Klasse zuzugreifen.MyBase
ist ein Schlüsselwort, kein echtes Objekt.MyBase
kann nicht einer Variablen zugewiesen, an Prozeduren übergeben oder in einemIs
-Vergleich verwendet werden.Die Methode, die
MyBase
qualifiziert, muss nicht in der unmittelbaren Basisklasse definiert werden. Sie kann stattdessen in einer indirekt geerbten Basisklasse definiert werden. Damit ein mittelsMyBase
qualifizierter Verweis ordnungsgemäß kompiliert werden kann, muss eine Basisklasse eine Methode enthalten, die dem Namen und den Parametertypen entspricht, die im Aufruf vorkommen.Sie können nicht
MyBase
verwenden, umMustOverride
Basisklassenmethoden aufzurufen.MyBase
kann nicht verwendet werden, um sich selbst zu qualifizieren. Daher ist der folgende Code ungültig:MyBase.MyBase.BtnOK_Click()
MyBase
kann nicht in Modulen verwendet werden.MyBase
kann nicht verwendet werden, um auf Basisklassenmember zuzugreifen, die alsFriend
gekennzeichnet sind, wenn sich die Basisklasse in einer anderen Assembly befindet.
Weitere Informationen und ein anderes Beispiel finden Sie unter Gewusst wie: Zugreifen auf eine Variable, die von einer abgeleiteten Klasse ausgeblendet wird.
Das Schlüsselwort „MyClass“
Das Schlüsselwort MyClass
verhält sich wie eine Objektvariable, die auf die aktuelle Instanz einer Klasse verweist, wie sie ursprünglich implementiert wurde. MyClass
ähnelt Me
, aber jeder Methoden- und Eigenschaftsaufruf an MyClass
wird so behandelt, als wäre die Methode oder Eigenschaft NotOverridable. Daher wird die Methode oder Eigenschaft nicht durch Überschreiben in einer abgeleiteten Klasse beeinflusst.
MyClass
ist ein Schlüsselwort, kein echtes Objekt.MyClass
kann nicht einer Variablen zugewiesen, an Prozeduren übergeben oder in einemIs
-Vergleich verwendet werden.MyClass
bezieht sich auf die enthaltende Klasse und ihre geerbten Member.MyClass
kann als Qualifizierer fürShared
Member verwendet werden.MyClass
kann nicht innerhalb einerShared
Methode verwendet werden, kann aber innerhalb einer Instanzmethode verwendet werden, um auf einen freigegebenen Member einer Klasse zuzugreifen.MyClass
kann nicht in Standardmodulen verwendet werden.MyClass
kann verwendet werden, um eine Methode zu qualifizieren, die in einer Basisklasse definiert ist und über keine Implementierung der in dieser Klasse bereitgestellten Methode verfügt. Ein solcher Verweis hat die gleiche Bedeutung wieMyBase.
Method.
Im folgenden Beispiel wird Me
mit MyClass
verglichen.
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
Obwohl derivedClass
testMethod
überschreibt, annulliert das Schlüsselwort MyClass
in useMyClass
die Auswirkungen des Überschreibens, und der Compiler löst den Aufruf zur Basisklassenversion von testMethod
auf.