Основы наследования (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 Если используется ключевое слово, определение метода состоит только SubFunctionиз инструкции или 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.

См. также