Esta es una de una miniserie que cubre las diferencias en sobrecargas, sombras y anulaciones en VB.NET. Este artículo cubre Overrides. Los artículos que cubren a los demás están aquí:
– & amp; gt; Sobrecargas
& lt; br & gt ;
– & amp; gt; Sombras & lt; / br & gt ;
Estas técnicas pueden ser enormemente confusas; Hay muchas combinaciones de estas palabras clave y las opciones de herencia subyacentes. La propia documentación de Microsoft & amp; apos; 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: & amp; quot; Prueba, prueba y prueba nuevamente.& amp; quot; En esta serie, nosotros & amp; apos; los veremos uno a la vez con énfasis en las diferencias.
Anulaciones
Lo que las sombras, las sobrecargas y las anulaciones tienen en común es que reutilizan el nombre de los elementos mientras cambian lo que sucede. Las sombras y sobrecargas pueden operar tanto dentro de la misma clase como cuando una clase hereda otra clase. Sin embargo, los anulados solo se pueden usar en una clase derivada (a veces llamada clase de niño) que hereda de una clase base (a veces llamada clase de padre). Y Overrides es el martillo; le permite reemplazar completamente un método (o una propiedad) de una clase base.
En el artículo sobre clases y la palabra clave Sombras (Ver: Sombras en VB.NET), se agregó una función para mostrar que se puede hacer referencia a un procedimiento heredado.
& lt; pre & gt ;
Clase pública ProfessionalContact
& amp; apos ; . código no mostrado .Public Function HashTheName (
ByVal nm como cadena) como cadena
Devolución nm.GetHashCode
Función final
Fin de clase
& lt; / pre & gt ;
Video destacado
El código que instantiza una clase derivada de esta (CodedProfessionalContact en el ejemplo) puede llamar a este método porque se heredó.
En el ejemplo, utilicé el método VB.NET GetHashCode para mantener el código simple y esto arrojó un resultado bastante inútil, el valor -520086483. Supongamos que quisiera que se devolviera un resultado diferente pero
– & amp; gt; Puedo & amp; apos; t cambiar la clase base. (Tal vez todo lo que tengo es un código compilado de un proveedor.)
y .
.
– & amp; gt; Puedo & amp; apos; t cambiar el código de llamada (tal vez hay mil copias y puedo & amp; apos; t 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 Overrides. Pero las bibliotecas de códigos bien diseñadas lo proporcionan. ( Sus bibliotecas de códigos están bien diseñadas, ¿verdad??) Por ejemplo, la función proporcionada por Microsoft que acabamos de usar es demasiado ridícula. Aquí y amp; apos; s un ejemplo de la sintaxis.
Función pública anular GetHashCode como entero
Entonces esa palabra clave también debe estar presente en nuestra clase base de ejemplo.
& lt; pre & gt ;
Función pública anular HashTheName (
ByVal nm como cadena) como cadena
& lt; / pre & gt ;
Anular el método ahora es tan simple como proporcionar uno nuevo con la palabra clave Anular. Visual Studio nuevamente le brinda un inicio continuo al completar el código para usted con AutoComplete.Cuando entras …
& lt; pre & gt ;
Función de anulaciones públicas HashTheName (
& lt; / pre & gt ;
Visual Studio agrega el resto del código automáticamente tan pronto como escribe el paréntesis de apertura, incluida la instrucción de retorno que solo llama a la función original de la clase base. (Si usted y otros están agregando algo, esto generalmente es algo bueno después de que su nuevo código se ejecute de todos modos.)
& lt; pre & gt ;
Función de anulaciones públicas HashTheName (
nm como cadena) como cadena
Devuelve MyBase.HashTheName (nm)
Función final
& lt; / pre & gt ;
En este caso, sin embargo, I & amp; apos; voy a reemplazar el método con algo igualmente inútil solo para ilustrar cómo se hizo & amp; apos; s: la función VB.NET que revertirá la cadena.
& lt; pre & gt ;
Función de anulaciones públicas HashTheName (
nm como cadena) como cadena
Devuelve Microsoft.VisualBasic.StrReverse (nm)
Función final
& lt; / pre & gt ;
Ahora el código de llamada obtiene un resultado completamente diferente. (Compare con el resultado en el artículo sobre Shadows.)
& lt; pre & gt ;
ContactID: 246
BusinessName: Villain Defeaters, GmbH
Hash of the BusinessName :
HbmG, sretaefeD nialliV
& lt; / pre & gt ;
También puede anular propiedades. Suponga que decidió que los valores de ContactID superiores a 123 no estarían permitidos y deberían ser predeterminados a 111. Simplemente puede anular la propiedad y cambiarla cuando se guarda la propiedad:
& lt; pre & gt ;
Privado _ContactID como entero
El público anula la propiedad ContactID como entero
Obtener
Devolución _ContactID
Fin Obtener
Establecer (valor ByVal como entero)
Si valor & amp; gt; 123 entonces
_ContactID = 111
De lo contrario
_ContactID = valor
Fin si
Conjunto final
Fin de la propiedad
& lt; / pre & gt ;
Luego obtienes este resultado cuando se pasa un valor mayor:
& lt; pre & gt ;
ContactID: 111
BusinessName: Damsel Rescuers, LTD
& lt; / pre & gt ;
Por cierto, en el código de ejemplo hasta ahora, los valores enteros se duplican en la Nueva subrutina (Ver el artículo en Sombras), por lo que un número entero de 123 se cambia a 246 y luego se cambia nuevamente 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 anule usando las palabras clave MustOverride y NotOverridable en la clase base. Pero ambos se usan en casos bastante específicos. Primero, no es anulable.
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:
& amp; apos; NotOverridable & amp; apos; 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 detenerse allí, debe especificar NotOverridable en ese método. En nuestro código de ejemplo:
& lt; pre & gt ;
Anulado público no anulable Función HashTheName ( …
& lt; / pre & gt ;
Entonces, si la clase CodedProfessionalContact es, a su vez, heredada …
& lt; pre & gt ;
Clase pública no anulableEx
Heredados codificadosContacto profesional
& lt; / pre & gt ;
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 la Fundación .NET es exigir que el propósito de cada clase se defina explícitamente para eliminar toda incertidumbre. Se ha llamado un problema en los idiomas OOP anteriores & amp; # x201C; la clase base frágil.&erio; # x201D; Esto sucede cuando una clase base agrega un nuevo método con el mismo nombre que un nombre de método en una subclase que hereda de una clase base. 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 resultó en el grito del programador herido, & amp; quot; no cambié nada, pero mi programa se bloqueó de todos modos.& amp; quot; Si existe la posibilidad de que una clase se actualice en el futuro y cree este problema, declare que no es anulable.
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 usted y amp; appos; la llenen con su propio código. Microsoft proporciona este ejemplo de uno:
& lt; pre & gt ;
La máquina de lavado de clase pública debe heredar
Sub Nuevo ()
& amp; apos; El código para instanciar la clase va aquí.
Fin sub
Public MustOverride Sub Wash
Public MustOverride Sub Rinse (loadSize as Integer)
Función de anulación de mosto público Gire (velocidad como entero) tan largo
Fin de clase
& lt; / pre & gt ;
Para continuar con el ejemplo de Microsoft & amp; apos; s, 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 hereda esta las defina . 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 anule usando las palabras clave MustOverride y NotOverridable en la clase base. Pero ambos se usan en casos bastante específicos. Primero, no es anulable.
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:
& amp; apos; NotOverridable & amp; apos; 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 detenerse allí, debe especificar NotOverridable en ese método. En nuestro código de ejemplo:
& lt; pre & gt ;
Anulado público no anulable Función HashTheName ( …
& lt; / pre & gt ;
Entonces, si la clase CodedProfessionalContact es, a su vez, heredada …
& lt; pre & gt ;
Clase pública no anulableEx
Heredados codificadosContacto profesional
& lt; / pre & gt ;
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 la Fundación .NET es exigir que el propósito de cada clase se defina explícitamente para eliminar toda incertidumbre. Se ha llamado un problema en los idiomas OOP anteriores & amp; # x201C; la clase base frágil.&erio; # x201D; Esto sucede cuando una clase base agrega un nuevo método con el mismo nombre que un nombre de método en una subclase que hereda de una clase base. 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 resultó en el grito del programador herido, & amp; quot; no cambié nada, pero mi programa se bloqueó de todos modos.& amp; quot; Si existe la posibilidad de que una clase se actualice en el futuro y cree este problema, declare que no es anulable.
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 usted y amp; appos; la llenen con su propio código. Microsoft proporciona este ejemplo de uno:
& lt; pre & gt ;
La máquina de lavado de clase pública debe heredar
Sub Nuevo ()
& amp; apos; El código para instanciar la clase va aquí.
Fin sub
Public MustOverride Sub Wash
Public MustOverride Sub Rinse (loadSize as Integer)
Función de anulación de mosto público Gire (velocidad como entero) tan largo
Fin de clase
& lt; / pre & gt ;
Para continuar con el ejemplo de Microsoft & amp; apos; s, 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 hereda esta las defina . 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
& amp; # x203A; Informática