Esta es una de una miniserie que cubre las diferencias en Sobrecargas, Sombras y Anulaciones en VB.NET. Este artículo cubre anulaciones. Los artículos que cubren los otros están aquí:
-> Sobrecargas
-> Sombras
Estas tecnicas puede ser muy confuso; Hay muchas combinaciones de estas palabras clave y las opciones de herencia subyacentes. La propia documentación de Microsoft no comienza a hacer justicia al tema y hay mucha información mala o desactualizada en la web. El mejor consejo para asegurarse de que su programa esté codificado correctamente es: "Prueba, prueba y prueba de nuevo". En esta serie, los veremos uno a la vez con énfasis en las diferencias.
Anulaciones
Lo que tienen en común Shadows, Overloads y Overrides es que reutilizan el nombre de los elementos mientras cambian lo que sucede. Las sombras y las sobrecargas pueden funcionar tanto dentro de la misma clase como cuando la clase hereda otra clase. Sin embargo, las anulaciones solo se pueden usar en una clase derivada (a veces llamada clase secundaria) que hereda de un
clase base (a veces llamada clase para padres). Y Overrides es el martillo; le permite reemplazar completamente un método (o una propiedad) de una clase base.En el artículo sobre las clases y la palabra clave Shadows (Ver: Shadows en VB.NET), se agregó una función para mostrar que se puede hacer referencia a un procedimiento heredado.
Contacto profesional de clase pública. '... código no mostrado... Función pública HashTheName ( ByVal nm como cadena) como cadena. Retorno nm. GetHashCode. Función final Fin de clase.
El código que crea una instancia de una clase derivada de este (CodedProfessionalContact en el ejemplo) puede llamar a este método porque se hereda.
En el ejemplo, usé el VB.NET GetHashCode método para mantener el código simple y esto devolvió un resultado bastante inútil, el valor -520086483. Supongamos que quisiera un resultado diferente devuelto, pero
-> No puedo cambiar la clase base. (Quizás todo lo que tengo es código compilado de un proveedor).
... y ...
-> No puedo cambiar el código de llamada (Tal vez hay mil copias y no puedo actualizarlas).
Si puedo actualizar la clase derivada, entonces puedo cambiar el resultado devuelto. (Por ejemplo, el código podría ser parte de una DLL actualizable).
Hay un problema Debido a que es tan completo y poderoso, debe tener permiso de la clase base para usar Invalidaciones. Pero las bibliotecas de código bien diseñadas lo proporcionan. (Tu todas las bibliotecas de códigos están bien diseñadas, ¿verdad?) Por ejemplo, la función proporcionada por Microsoft que acabamos de usar es invalidable. Aquí hay un ejemplo de la sintaxis.
Función pública anulable GetHashCode como entero
Así que esa palabra clave también debe estar presente en nuestra clase base de ejemplo.
Función pública reemplazable HashTheName ( ByVal nm como cadena) como cadena.
Anulando el método ahora es tan simple como proporcionar uno nuevo con la palabra clave Overrides. Visual Studio nuevamente le da un comienzo continuo al completar el código por usted con Autocompletar. Cuando usted entre ...
La función de anulación pública HashTheName (
Visual Studio agrega el resto del código automáticamente tan pronto como escribe el paréntesis de apertura, incluida la instrucción return que solo llama a la función original de la clase base. (Si solo está agregando algo, esto suele ser algo bueno después de que su nuevo código se ejecute de todos modos).
La función de anulación pública HashTheName ( nm como cadena) como cadena. Regrese MyBase. HashTheName (nm) Función final
En este caso, sin embargo, voy a reemplazar el método con otra cosa igualmente inútil solo para ilustrar cómo se hace: la función VB.NET que revertirá la cadena.
La función de anulación pública HashTheName ( nm como cadena) como cadena. Devuelve Microsoft. VisualBasic. StrReverse (nm) Función final
Ahora el código de llamada obtiene un resultado completamente diferente. (Compare con el resultado en el artículo sobre Sombras).
ID de contacto: 246. Nombre comercial: Villain Defeaters, GmbH. Hash del Negocio Nombre: HbmG, sretaefeD nialliV.
También puede anular las propiedades. Suponga que decidió que los valores de ContactID superiores a 123 no se permitirían y deberían predeterminarse a 111. Puede anular la propiedad y cambiarla cuando se guarda la propiedad:
Private _ContactID como entero. El público anula la propiedad ContactID como entero. Obtener. Devuelve _ContactID. Fin Get. Establecer (valor ByVal como entero) Si valor> 123 Entonces. _ContactID = 111. Más. _ContactID = valor. Terminara si. Fin de conjunto. Fin de la propiedad.
Luego obtienes este resultado cuando se pasa un valor mayor:
ID de contacto: 111. Nombre comercial: Damsel Rescuers, LTD.
Por cierto, en el código de ejemplo hasta ahora, los valores enteros se duplican en el Nuevo subrutina (Consulte el artículo sobre Sombras), por lo que un número entero de 123 se cambia a 246 y luego se vuelve a cambiar a 111.
VB.NET le brinda, aún más, control al permitir que una clase base requiera o niegue específicamente que una clase derivada se anule utilizando las palabras clave MustOverride y NotOverridable en la clase base. Pero ambos se usan en casos bastante específicos. Primero, no superable.
Dado que el valor predeterminado para una clase pública es NotOverridable, ¿por qué debería necesitar especificarlo? Si lo prueba en la función HashTheName en la clase base, obtiene un error de sintaxis, pero el texto del mensaje de error le da una pista:
'NotOverridable' no se puede especificar para métodos que no anulan otro método.
El valor predeterminado para un método anulado es todo lo contrario: Anulable. Entonces, si desea anular definitivamente para detenerse allí, debe especificar NotOverridable en ese método. En nuestro código de ejemplo:
Público no superable Anulaciones Función HashTheName (...
Entonces, si la clase CodedProfessionalContact es, a su vez, heredada ...
Clase pública NotOverridableEx. Hereda el contacto profesional codificado.
... la función HashTheName no se puede anular en esa clase. Un elemento que no se puede anular a veces se denomina elemento sellado.
Una parte fundamental de el .Fundación NET es exigir que el propósito de cada clase se defina explícitamente para eliminar toda incertidumbre. Un problema en los lenguajes OOP anteriores se ha denominado "la clase base frágil". Esto sucede cuando una base La clase agrega un nuevo método con el mismo nombre que el nombre de un método en una subclase que hereda de una base clase. El programador que escribió la subclase no planeó anular la clase base, pero esto es exactamente lo que sucede de todos modos. Se sabe que esto provocó el grito del programador herido: "No cambié nada, pero mi programa falló de todos modos ". Si existe la posibilidad de que una clase se actualice en el futuro y cree este problema, declare como No superable.
MustOverride se usa con mayor frecuencia en lo que se llama una clase abstracta. (¡En C #, lo mismo usa la palabra clave Resumen!) Esta es una clase que solo proporciona una plantilla y se espera que la complete con su propio código. Microsoft proporciona este ejemplo de uno:
Público debe heredar la clase Lavadora. Sub nuevo () El código para instanciar la clase va aquí. Fin sub. El público debe anular el lavado secundario. Public MustOverride Sub Rinse (loadSize as Integer) La función Public MustOverride Spin (velocidad como número entero) como larga. Fin de clase.
Para continuar con el ejemplo de Microsoft, las lavadoras harán estas cosas (lavado, enjuague y centrifugado) de manera bastante diferente, por lo que no hay ninguna ventaja de definir la función en la clase base. Pero hay una ventaja en asegurarse de que cualquier clase que herede esta hace definirlos La solución: una clase abstracta.
Si necesita aún más explicaciones sobre las diferencias entre Sobrecargas y Anulaciones, se desarrolla un ejemplo completamente diferente en un Consejo rápido: Sobrecargas versus anulaciones
VB.NET le brinda aún más control al permitir que una clase base requiera o niegue específicamente que una clase derivada se anule usando las palabras clave MustOverride y NotOverridable en la clase base. Pero ambos se usan en casos bastante específicos. Primero, no superable.
Dado que el valor predeterminado para una clase pública es NotOverridable, ¿por qué debería necesitar especificarlo? Si lo prueba en la función HashTheName en la clase base, obtiene un error de sintaxis, pero el texto del mensaje de error le da una pista:
'NotOverridable' no se puede especificar para métodos que no anulan otro método.
El valor predeterminado para un método anulado es todo lo contrario: Anulable. Entonces, si desea anular definitivamente para detenerse allí, debe especificar NotOverridable en ese método. En nuestro código de ejemplo:
Público no superable Anulaciones Función HashTheName (...
Entonces, si la clase CodedProfessionalContact es, a su vez, heredada ...
Clase pública NotOverridableEx. Hereda el contacto profesional codificado.
... la función HashTheName no se puede anular en esa clase. Un elemento que no se puede anular a veces se denomina elemento sellado.
Una parte fundamental de .NET Foundation es exigir que el propósito de cada clase se defina explícitamente para eliminar toda incertidumbre. Un problema en los lenguajes OOP anteriores se ha denominado "la clase base frágil". Esto sucede cuando una base La clase agrega un nuevo método con el mismo nombre que el nombre de un método en una subclase que hereda de una base clase. El programador que escribió la subclase no planeó anular la clase base, pero esto es exactamente lo que sucede de todos modos. Se sabe que esto provocó el grito del programador herido: "No cambié nada, pero mi programa falló de todos modos ". Si existe la posibilidad de que una clase se actualice en el futuro y cree este problema, declare como No superable.
MustOverride se usa con mayor frecuencia en lo que se llama una clase abstracta. (¡En C #, lo mismo usa la palabra clave Resumen!) Esta es una clase que solo proporciona una plantilla y se espera que la complete con su propio código. Microsoft proporciona este ejemplo de uno:
Público debe heredar la clase Lavadora. Sub nuevo () El código para instanciar la clase va aquí. Fin sub. El público debe anular el lavado secundario. Public MustOverride Sub Rinse (loadSize as Integer) La función Public MustOverride Spin (velocidad como número entero) como larga. Fin de clase.
Para continuar con el ejemplo de Microsoft, las lavadoras harán estas cosas (lavado, enjuague y centrifugado) de manera bastante diferente, por lo que no hay ninguna ventaja de definir la función en la clase base. Pero hay una ventaja en asegurarse de que cualquier clase que herede esta hace definirlos La solución: una clase abstracta.
Si necesita aún más explicaciones sobre las diferencias entre Sobrecargas y Anulaciones, se desarrolla un ejemplo completamente diferente en un Consejo rápido: Sobrecargas versus anulaciones