Основы наследования (Visual Basic)
Оператор 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
null определяет эффекты переопределения, а компилятор разрешает вызов версии базового класса testMethod
.