継承の基本 (Visual Basic)
Inherits
ステートメントは、基底クラスと呼ばれる既存のクラスに基づいて、派生クラスと呼ばれる新しいクラスを宣言するために使用されます。 派生クラスは、基底クラスで定義されているプロパティ、メソッド、イベント、フィールド、および定数を継承し、これらを拡張することができます。 次のセクションでは、継承に関するいくつかの規則と、クラスが継承したり継承されたりする方法を変更するために使用できる修飾子について説明します。
既定では、
NotInheritable
キーワードでマークされていない限り、すべてのクラスが継承可能です。 クラスは、プロジェクト内の他のクラスから、またはプロジェクトが参照する他のアセンブリのクラスから継承できます。複数の継承を許可する言語とは異なり、Visual Basic ではクラスでの単一継承のみが許可されます。つまり、派生クラスは基底クラスを 1 つだけ持つことができます。 クラスでは複数の継承は許可されませんが、クラスは複数のインターフェイスを実装できます。これにより、同じ目的を効率的に実現できます。
基底クラスで制限された項目を公開しないようにするには、派生クラスのアクセスの種類がその基底クラスと同等以上に制限されている必要があります。 たとえば、
Public
クラスは、Friend
またはPrivate
クラスを継承できず、Friend
クラスはPrivate
クラスを継承できません。
継承修飾子
Visual Basic では、継承をサポートするために、次のクラスレベルのステートメントと修飾子が導入されています。
Inherits
ステートメント - 基底クラスを指定します。NotInheritable
修飾子 - プログラマがクラスを基底クラスとして使用できないようにします。MustInherit
修飾子 - クラスが基底クラスとしてのみ使用されることを指定します。MustInherit
クラスのインスタンスを直接作成することはできません。派生クラスの基底クラスのインスタンスとしてのみ作成できます。 (C++ や C# などの他のプログラミング言語では、このようなクラスについて説明するのに抽象クラスという用語を使用します。)
派生クラスのプロパティとメソッドのオーバーライド
既定では、派生クラスは基底クラスのプロパティとメソッドを継承します。 派生クラス内の継承されたプロパティまたはメソッドの動作が異なる場合は、オーバーライドできます。 つまり、派生クラスにメソッドの新しい実装を定義できます。 プロパティやメソッドのオーバーライド方法を制御するには、次の修飾子を使用します。
Overridable
- クラス内のプロパティまたはメソッドを派生クラスでオーバーライドできます。Overrides
- 基底クラスに定義されたOverridable
プロパティまたはメソッドをオーバーライドします。NotOverridable
- 継承するクラスでプロパティまたはメソッドがオーバーライドされないようにします。 既定では、Public
メソッドはNotOverridable
です。MustOverride
- 派生クラスでプロパティまたはメソッドをオーバーライドする必要があります。MustOverride
キーワードを使用する場合、メソッド定義は、Sub
、Function
、またはProperty
ステートメントだけで構成されます。 他のステートメントは許可されません。具体的には、End Sub
またはEnd Function
ステートメントはありません。MustOverride
メソッドはMustInherit
クラスで宣言する必要があります。
給与支払いを処理するクラスを定義するとします。 典型的な 1 週間の給与を計算する RunPayroll
メソッドを含むジェネリック Payroll
クラスを定義できます。 その後、より特殊化された BonusPayroll
クラスの基底クラスとして Payroll
を使用できます。これは、従業員の賞与を配分するときに使用できます。
BonusPayroll
クラスは、基底クラス Payroll
で定義されている PayEmployee
メソッドを継承し、オーバーライドできます。
次の例では、基底クラス、 Payroll
、および継承されたメソッドをオーバーライドする派生クラス BonusPayroll
を定義 PayEmployee
。 プロシージャ RunPayroll
は、Payroll
オブジェクトと BonusPayroll
オブジェクトを作成してから、両方のオブジェクトの PayEmployee
メソッドを実行する関数 Pay
に渡します。
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
MyBase キーワード
MyBase
キーワードは、クラスの現在のインスタンスの基底クラスを参照するオブジェクト変数のように動作します。 MyBase
は、派生クラスでオーバーライドまたはシャドウされた基底クラスのメンバーにアクセスするためによく使用されます。 特に、MyBase.New
は、派生クラスのコンストラクターから基底クラスのコンストラクターを明示的に呼び出すために使用されます。
たとえば、基底クラスから継承されたメソッドをオーバーライドする派生クラスを設計するとします。 オーバーライドされたメソッドは、次のコード フラグメントに示されている、基底クラスのメソッドを呼び出して、戻り値を変更することができます。
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
MyBase
の使用に関する制限事項を次の一覧に示します。
MyBase
は、直接の基底クラスとその継承メンバーを参照します。 クラス内のPrivate
メンバーへのアクセスには使用できません。MyBase
はキーワードであり、実際のオブジェクトではありません。MyBase
は、変数に割り当てたり、プロシージャに渡したり、Is
の比較で使用したりすることはできません。MyBase
で修飾されるメソッドは、直接の基底クラスで定義されている必要はありません。代わりに、間接的に継承された基底クラスで定義することができます。MyBase
によって修飾された参照を正しくコンパイルするために、一部の基底クラスには、呼び出しに存在するパラメーターの名前と型に一致するメソッドが含まれている必要があります。MyBase
を使用してMustOverride
基底クラスのメソッドを呼び出すことはできません。MyBase
を使用してそれ自体を修飾することはできません。 したがって、次のコードは有効ではありません。MyBase.MyBase.BtnOK_Click()
MyBase
はモジュールでは使用できません。MyBase
は、基底クラスが別のアセンブリにある場合にFriend
としてマークされている基底クラスのメンバーにアクセスするために使用することはできません。
詳細ともう 1 つの例については、「方法: 派生クラスによって非表示になっている変数にアクセスする」を参照してください。
MyClass キーワード
MyClass
キーワードは、もともと実装されているクラスの現在のインスタンスを参照するオブジェクト変数と同様に動作します。 MyClass
は Me
に似ていますが、MyClass
のすべてのメソッドとプロパティ呼び出しは、メソッドまたはプロパティが NotOverridable であるかのように扱われます。 したがって、メソッドまたはプロパティは、派生クラスでのオーバーライドによる影響を受けません。
MyClass
はキーワードであり、実際のオブジェクトではありません。MyClass
は、変数に割り当てたり、プロシージャに渡したり、Is
の比較で使用したりすることはできません。MyClass
は、含まれているクラスとその継承メンバーを参照します。MyClass
はShared
メンバーの修飾子として使用できます。MyClass
はShared
メソッド内では使用できませんが、インスタンス メソッド内で使用して、クラスの共有メンバーにアクセスすることができます。MyClass
は標準モジュールでは使用できません。MyClass
は、基底クラスで定義されていて、そのクラスで提供されるメソッドの実装を持たないメソッドを修飾するために使用できます。 このような参照は、MyBase.
メソッドと同じ意味を持ちます。
次の例では、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
derivedClass
が testMethod
をオーバーライドしても、useMyClass
の MyClass
キーワードがオーバーライドの効果を無効にし、コンパイラは testMethod
の基底クラスのバージョンの呼び出しを解決します。
関連項目
.NET