Substituições no VB.NET

Esta é uma das minisséries que aborda as diferenças em Sobrecargas, Sombras e Substituições em VB.NET. Este artigo aborda substituições. Os artigos que cobrem os outros estão aqui:

-> Sobrecargas
-> Sombras

Essas técnicas pode ser extremamente confuso; existem muitas combinações dessas palavras-chave e das opções de herança subjacentes. A documentação da própria Microsoft não começa a fazer justiça ao tópico e há muitas informações ruins ou desatualizadas na web. O melhor conselho para garantir que seu programa esteja codificado corretamente é "Teste, teste e teste novamente". Nesta série, veremos um de cada vez, com ênfase nas diferenças.

Substituições

O que Sombras, Sobrecargas e Substituições têm em comum é que eles reutilizam o nome dos elementos enquanto alteram o que acontece. Sombras e sobrecargas podem operar na mesma classe ou quando um classe herda outra classe. As substituições, no entanto, só podem ser usadas em uma classe derivada (às vezes chamada de classe filho) que herda de uma classe

instagram viewer
classe base (às vezes chamada de classe pai). E Overrides é o martelo; permite substituir totalmente um método (ou uma propriedade) de uma classe base.

No artigo sobre classes e a palavra-chave Shadows (consulte: Shadows in VB.NET), uma função foi adicionada para mostrar que um procedimento herdado pode ser referenciado.

Classe Pública ProfessionalContact. '... código não mostrado... Função pública HashTheName ( ByVal nm Como String) Como String. Retorno nm. GetHashCode. Função final. Classe final.

O código que instancia uma classe derivada dessa (CodedProfessionalContact no exemplo) pode chamar esse método porque é herdado.

No exemplo, eu usei o VB.NET GetHashCode método para manter o código simples e isso retornou um resultado bastante inútil, o valor -520086483. Suponha que eu desejasse um resultado diferente retornado, mas,

-> Não posso mudar a classe base. (Talvez tudo o que tenho seja o código compilado de um fornecedor.)

... e ...

-> Não consigo alterar o código de chamada (talvez haja mil cópias e não possa atualizá-las).

Se eu puder atualizar a classe derivada, posso alterar o resultado retornado. (Por exemplo, o código pode fazer parte de uma DLL atualizável.)

Há um problema. Por ser tão abrangente e poderoso, você precisa ter permissão da classe base para usar Substituições. Mas as bibliotecas de código bem projetadas fornecem isso. (Seu todas as bibliotecas de código são bem projetadas, certo?) Por exemplo, a função fornecida pela Microsoft que acabamos de usar é substituível. Aqui está um exemplo da sintaxe.

Função pública substituível GetHashCode como número inteiro

Portanto, essa palavra-chave também deve estar presente em nossa classe base de exemplo.

Função pública substituível HashTheName ( ByVal nm Como String) Como String.

Substituindo o método agora é tão simples quanto fornecer uma nova com a palavra-chave Substituições. O Visual Studio novamente fornece um início de execução preenchendo o código para você com o AutoCompletar. Quando você entra ...


Substituições públicas Função HashTheName (

O Visual Studio adiciona o restante do código automaticamente assim que você digita o parêntese de abertura, incluindo a declaração de retorno, que chama apenas a função original da classe base. (Se você está apenas adicionando algo, geralmente é uma coisa boa a fazer depois que seu novo código é executado.)

Substituições públicas Função HashTheName ( nm Como String) Como String. Retorne o MyBase. HashTheName (nm) Função final.

Neste caso, no entanto, vou substituir o método por algo igualmente inútil apenas para ilustrar como é feito: A função VB.NET que reverterá a string.

Substituições públicas Função HashTheName ( nm Como String) Como String. Retornar Microsoft. Visual básico. StrReverse (nm) Função final.

Agora, o código de chamada obtém um resultado totalmente diferente. (Compare com o resultado no artigo sobre Shadows.)


ID do contato: 246. Nome da empresa: Villain Defeaters, GmbH. Hash do nome comercial: HbmG, sretaefeD nialliV. 

Você pode substituir propriedades também. Suponha que você tenha decidido que valores de ContactID maiores que 123 não seriam permitidos e que deveriam usar como padrão 111. Você pode simplesmente substituir a propriedade e alterá-la quando a propriedade for salva:

Private _ContactID Como Inteiro. Propriedade pública substitui ContactID como inteiro. Obter. Retornar _ContactID. End Get. Definir (valor ByVal como inteiro) Se valor> 123 Então. _ContactID = 111. Outro. _ContactID = valor. Fim se. Finalizar conjunto. Propriedade final.

Então você obtém esse resultado quando um valor maior é passado:


ID do contato: 111. Nome da empresa: Damsel Rescuers, LTD. 

A propósito, no código de exemplo até agora, os valores inteiros são dobrados no Novo sub-rotina (Consulte o artigo sobre Sombras), portanto, um número inteiro de 123 é alterado para 246 e, em seguida, alterado novamente para 111.

O VB.NET oferece ainda mais controle, permitindo que uma classe base exija ou negue especificamente que uma classe derivada substitua usando as palavras-chave MustOverride e NotOverridable na classe base. Mas ambos são usados ​​em casos bastante específicos. Primeiro, não exagerável.

Como o padrão para uma classe pública é NotOverridable, por que você precisa especificá-lo? Se você tentar na função HashTheName na classe base, receberá um erro de sintaxe, mas o texto da mensagem de erro fornece uma pista:

'NotOverridable' não pode ser especificado para métodos que não substituem outro método.

O padrão para um método substituído é exatamente o oposto: Substituível. Portanto, se você deseja substituir definitivamente para por aí, é necessário especificar NotOverridable nesse método. No nosso código de exemplo:


Público NotOverridable Substituições Função HashTheName (... 

Então, se a classe CodedProfessionalContact for, por sua vez, herdada ...


Classe pública NotOverridableEx. Herda o código de contato profissional. 

... a função HashTheName não pode ser substituída nessa classe. Um elemento que não pode ser substituído é chamado de elemento selado.

Uma parte fundamental de a .Fundação NET é exigir que o objetivo de cada classe seja explicitamente definido para remover toda a incerteza. Um problema nas linguagens OOP anteriores foi chamado de "a classe base frágil". Isso acontece quando uma base A classe adiciona um novo método com o mesmo nome que um nome de método em uma subclasse que herda de uma base classe. O programador que escrevia a subclasse não planejava substituir a classe base, mas é exatamente isso que acontece de qualquer maneira. Sabe-se que isso resultou no grito do programador ferido: "Eu não mudei nada, mas meu programa travou "Se houver a possibilidade de uma classe ser atualizada no futuro e criar esse problema, declare-a como NotOverridable.

O MustOverride é usado com mais freqüência no que é chamado de Classe Abstrata. (Em C #, a mesma coisa usa a palavra-chave Resumo!) Essa é uma classe que apenas fornece um modelo e você deve preenchê-lo com seu próprio código. A Microsoft fornece este exemplo de um:

Classe pública MustInherit WashingMachine. Sub-novo () 'O código para instanciar a classe vai aqui. End sub. Public MustOverride Sub Wash. Public MustOverride Sub Rinse (loadSize como Inteiro) Função pública MustOverride Spin (velocidade como Inteiro) como Long. Classe final.

Para continuar o exemplo da Microsoft, as máquinas de lavar fazem essas coisas (Lavar, Enxaguar e Girar) de maneira bem diferente, portanto não há vantagem em definir a função na classe base. Mas há uma vantagem em garantir que qualquer classe que herda essa faz defini-los. A solução: uma classe abstrata.

Se você precisar de mais explicações sobre as diferenças entre Sobrecargas e Substituições, um exemplo completamente diferente será desenvolvido em uma Dica rápida: Sobrecargas versus substituições

O VB.NET oferece ainda mais controle, permitindo que uma classe base exija ou negue especificamente que uma classe derivada substitua usando as palavras-chave MustOverride e NotOverridable na classe base. Mas ambos são usados ​​em casos bastante específicos. Primeiro, não exagerável.

Como o padrão para uma classe pública é NotOverridable, por que você precisa especificá-lo? Se você tentar na função HashTheName na classe base, receberá um erro de sintaxe, mas o texto da mensagem de erro fornece uma pista:

'NotOverridable' não pode ser especificado para métodos que não substituem outro método.

O padrão para um método substituído é exatamente o oposto: Substituível. Portanto, se você deseja substituir definitivamente para por aí, é necessário especificar NotOverridable nesse método. No nosso código de exemplo:


Público NotOverridable Substituições Função HashTheName (... 

Então, se a classe CodedProfessionalContact for, por sua vez, herdada ...


Classe pública NotOverridableEx. Herda o código de contato profissional. 

... a função HashTheName não pode ser substituída nessa classe. Um elemento que não pode ser substituído é chamado de elemento selado.

Uma parte fundamental do .NET Foundation é exigir que o objetivo de cada classe seja explicitamente definido para remover toda a incerteza. Um problema nas linguagens OOP anteriores foi chamado de "a classe base frágil". Isso acontece quando uma base A classe adiciona um novo método com o mesmo nome que um nome de método em uma subclasse que herda de uma base classe. O programador que escrevia a subclasse não planejava substituir a classe base, mas é exatamente isso que acontece de qualquer maneira. Sabe-se que isso resultou no grito do programador ferido: "Eu não mudei nada, mas meu programa travou "Se houver a possibilidade de uma classe ser atualizada no futuro e criar esse problema, declare-a como NotOverridable.

O MustOverride é usado com mais freqüência no que é chamado de Classe Abstrata. (Em C #, a mesma coisa usa a palavra-chave Resumo!) Essa é uma classe que apenas fornece um modelo e você deve preenchê-lo com seu próprio código. A Microsoft fornece este exemplo de um:

Classe pública MustInherit WashingMachine. Sub-novo () 'O código para instanciar a classe vai aqui. End sub. Public MustOverride Sub Wash. Public MustOverride Sub Rinse (loadSize como Inteiro) Função pública MustOverride Spin (velocidade como Inteiro) como Long. Classe final.

Para continuar o exemplo da Microsoft, as máquinas de lavar fazem essas coisas (Lavar, Enxaguar e Girar) de maneira bem diferente, portanto não há vantagem em definir a função na classe base. Mas há uma vantagem em garantir que qualquer classe que herda essa faz defini-los. A solução: uma classe abstrata.

Se você precisar de mais explicações sobre as diferenças entre Sobrecargas e Substituições, um exemplo completamente diferente será desenvolvido em uma Dica rápida: Sobrecargas versus substituições