Compartilhar via


Noções básicas de herança (Visual Basic)

A instrução Inherits é usada para declarar uma nova classe, chamada de classe derivada, com base em uma classe existente, conhecida como classe base. As classes derivadas herdam e podem estender as propriedades, os métodos, os eventos, os campos e as constantes definidos na classe base. A seção a seguir descreve algumas das regras de herança e os modificadores que você pode usar para alterar a forma como as classes herdam ou são herdadas:

  • Por padrão, todas as classes são hereditárias, a menos que marcadas com a palavra-chave NotInheritable. As classes podem herdar de outras classes no projeto ou de classes em outros assemblies referenciados pelo projeto.

  • Ao contrário das linguagens que permitem várias heranças, o Visual Basic permite apenas a herança única para classes, ou seja, as classes derivadas podem ter apenas uma classe base. Embora não sejam permitidas várias heranças para classes, as classes podem implementar várias interfaces, que podem realizar de fato as mesmas finalidades.

  • Para evitar a exposição de itens restritos em uma classe base, o tipo de acesso de uma classe derivada deve ser igual ou mais restritivo do que o da classe base. Por exemplo, uma classe Public não pode herdar uma classe Friend ou Private, e uma classe Friend não pode herdar uma classe Private.

Modificador de Herança

O Visual Basic apresenta as seguintes instruções de nível de classe e modificadores para permitir a herança:

  • Instrução Inherits – especifica a classe base.

  • Modificador NotInheritable – Impede que os programadores usem a classe como classe base.

  • Modificador MustInherit – Especifica que a classe se destina a ser usada apenas como classe base. Não é possível criar diretamente as instâncias das classes MustInherit. Elas só podem ser criadas como instâncias da classe base de uma classe derivada. (Outras linguagens de programação, como C++ e C#, usam o termo classe abstrata para descrever essa classe.)

Substituição de Propriedades e Métodos em Classes Derivadas

Por padrão, uma classe derivada herda as propriedades e os métodos da classe base. Se for necessário que uma propriedade ou método herdado se comporte de forma diferente na classe derivada, ele pode ser substituído. Ou seja, você pode definir uma nova implementação do método na classe derivada. Os seguintes modificadores são usados para controlar como as propriedades e métodos são substituídos:

  • Overridable – Permite que uma propriedade ou método em uma classe seja substituído em uma classe derivada.

  • Overrides – Substitui uma propriedade ou método Overridable definido na classe base.

  • NotOverridable – Impede que uma propriedade ou método seja substituído em uma classe herdada. Por padrão, os métodos Public são NotOverridable.

  • MustOverride – Requer que uma classe derivada substitua a propriedade ou o método. Quando a palavra-chave MustOverride é usada, a definição do método consiste apenas na instrução Sub, Function ou Property. Nenhuma outra instrução é permitida e, especificamente, não há uma instrução End Sub ou End Function. Os métodos MustOverride devem ser declarados em classes MustInherit.

Suponha que você queira definir classes para lidar com a folha de pagamento. Você pode definir uma classe genérica Payroll que contém um método RunPayroll que calcula a folha de pagamento para uma semana típica. Em seguida, você pode usar Payroll como classe base para uma classe mais especializada BonusPayroll, que pode ser usada ao distribuir bônus de funcionário.

A classe BonusPayroll pode herdar e substituir o PayEmployee método definido na classe base Payroll.

O exemplo a seguir define uma classe base, Payroll, e uma classe derivada, BonusPayroll, que substitui um método herdado, PayEmployee. Um procedimento, RunPayroll, cria e passa um objeto Payroll e um objeto BonusPayroll para uma função, Pay, que executa o método PayEmployee de ambos os objetos.

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

A palavra-chave MyBase

A palavra-chave MyBase se comporta como uma variável de objeto, que se refere à classe base da instância atual de uma classe. MyBase é usado com frequência para acessar os membros da classe base substituídos ou sombreados em uma classe derivada. Em particular, MyBase.New é usado para chamar explicitamente um construtor de classe base em um construtor de classe derivada.

Por exemplo, suponha que você esteja criando uma classe derivada que substitui um método herdado da classe base. O método substituído pode chamar o método na classe base e modificar o valor retornado, conforme mostrado no fragmento de código a seguir:

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

A lista a seguir descreve as restrições de uso de MyBase:

  • MyBase se refere à classe base imediata e os membros herdados. Ele não pode ser usado para acessar Private membros na classe.

  • MyBase é uma palavra-chave, não um objeto real. MyBase não pode ser atribuído a uma variável, passado para os procedimentos nem usado em uma comparação Is.

  • O método qualificado por MyBase não precisa ser definido na classe base imediata. Em vez disso, pode ser definido em uma classe base herdada indiretamente. Para obter uma referência qualificada por MyBase para compilar corretamente, algumas classes base devem conter um método correspondente ao nome e aos tipos de parâmetros exibidos na chamada.

  • Você não pode usar MyBase para chamar os métodos de classe base MustOverride.

  • MyBase não pode ser usado para se qualificar. Portanto, o código a seguir não é válido:

    MyBase.MyBase.BtnOK_Click()

  • MyBase não pode ser usado em módulos.

  • MyBase não pode ser usado para acessar os membros da classe base marcados como Friend, se a classe base estiver em um assembly diferente.

Para obter mais informações e outro exemplo, confira Instruções: acessar uma variável oculta por uma classe derivada.

A palavra-chave MyClass

A palavra-chave MyClass se comporta como uma variável de objeto, que se refere à instância atual de uma classe conforme a implementação original. MyClass é semelhante a Me, mas cada método e chamada de propriedade em MyClass é tratado como se o método ou a propriedade fosse NotOverridable. Portanto, o método ou a propriedade não é afetado pela substituição em uma classe derivada.

  • MyClass é uma palavra-chave, não um objeto real. MyClass não pode ser atribuído a uma variável, passado para os procedimentos nem usado em uma comparação Is.

  • MyClass se refere à classe relativa e os membros herdados.

  • MyClass pode ser usado como qualificador para membros Shared.

  • MyClass não pode ser usado dentro de um método Shared, mas pode ser usado dentro de um método de instância para acessar um membro compartilhado de uma classe.

  • MyClass não pode ser usado em módulos padrão.

  • MyClass pode ser usado para qualificar um método definido em uma classe base e que não tenha implementação do método fornecido nessa classe. Essa referência tem o mesmo significado de MyBase.Método.

O exemplo a seguir compara Me e 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

Embora derivedClass substitua testMethod, a palavra-chave MyClass em useMyClass anula os efeitos da substituição, e o compilador resolve a chamada para a versão de classe base de testMethod.

Confira também