Inherits 陳述式可用來根據現有類別 (稱為「基底類別」) 宣告新類別 (稱為「衍生類別」)。 衍生類別會繼承 (並可擴充) 基底類別中定義的屬性、方法、事件、欄位和常數。 下一節描述一些繼承規則,以及可用來變更類別繼承或被繼承方式的修飾詞:
根據預設,除非以
NotInheritable關鍵字標記,否則所有類別都是可繼承的。 類別可以繼承自專案中的其他類別,也可以繼承自專案所參考其他組件中的類別。不同於允許多重繼承的語言,Visual Basic 在類別中只允許單一繼承;也就是說,衍生類別只能有一個基底類別。 雖然類別中不允許多重繼承,但類別可以實作多個介面,因此可以有效地達成相同結果。
若要防止公開基底類別中受限制的項目,衍生類別的存取類型必須與其基底類別同樣嚴格或更嚴格。 例如,
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類別中宣告。
假設您想要定義類別來處理薪資。 您可以定義泛型 Payroll 類別,其中包含計算典型一週薪資的 RunPayroll 方法。 然後,您可以使用 Payroll,作為分配員工紅利時可能使用之更特製化 BonusPayroll 類別的基底類別。
BonusPayroll 類別可以繼承和覆寫基底 PayEmployee 類別中定義的 Payroll 方法。
下列範例會定義基類、 Payroll和衍生類別 , BonusPayroll其會覆寫繼承的方法 PayEmployee。
RunPayroll 程序會建立 Payroll 物件和 BonusPayroll 物件並接著傳遞給 Pay 函式,以執行這兩個物件的 PayEmployee 方法。
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的基底類別成員 (如果該基底類別位於不同的組件中)。
如需詳細資訊和其他範例,請參閱操作說明:存取衍生類別所隱藏的變數。
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,MyClass 中的 useMyClass 關鍵字也會使覆寫無效,而且編譯器會解析 testMethod 的基底類別版本呼叫。