sábado, 25 de enero de 2014

Ocultación de Miembros Heredados en C#

Tabla de Contenido

0. Introducción
1. Ocultación de Miembros Heredados
1.1 Construcción new (desambiguación: modificador)
1.2 Privatización de un miembro oculto
2. Ejemplo de Ocultación de Campo Miembro
3. new versus override
4. Conclusiones
5. Glosario
6. Enlaces & Literatura

0. Introducción

Casi por completar el mes sin una mínima actividad en el blog, reanudo mi proceso de escritura de artículos, recetas, ejercicios, aplicaciones, &c.

En esta oportunidad les hablaré acerca de la ocultación de miembros en C#. Ocurre con frecuencia mientras que heredamos miembros de un tipo sobre otro. Esta ocultación tiene un semejante cuando en un método eclipsa las campos de instancia por medio de las variables o parámetros declarados en la firma o en la implementación del método. Haré algunas demostraciones por medio de algunos ejemplos sencillos de herencia, y el uso de construcciones del lenguaje para alcanzar este comportamiento.

1. Ocultación de Miembros Heredados

En C# podemos ocultar miembros (funciones: métodos, propiedades, indezadores, eventos; y campos) a través de construcciones del lenguaje. Exactamente por medio de la palabra clave new [5]. En los ejemplos próximos, veremos que la ausencia de esta construcción, hace que el compilador arrojará una advertencia sobre el uso no adecuado y consciente de la ocultación del miembro heredado.

1.1 Construcción new (desambiguación: modificador)

Cuando usamos new en la definición de la firma de un método estamos explicitando que éste último va a ocultar la definición de la clase base. Vayamos con un par de ejemplos en donde se omite el uso de new, y en otro en donde se incluye.

En este primer ejemplo se omite el uso de la palabra clave new sobre la definición del método en la clase base:

Archivo OmisionNew.cs:



Cuando ponemos a prueba este archivo obtenemos:

► Prueba de ejecución.

El compilador arrojará la siguiente advertencia:

warning CS0108: 'ClaseDerivada.F()' hides inherited member 'ClaseBase.F()'. Use the new keyword if hiding was intended.

En este ejemplo se incluye la versión con el modificador new:

Archivo InclusionNew.cs:



Vemos que para explicitar la ocultación imponemos el modificar new en la misma firma del método F.

1.2 Privatización de un miembro oculto

Por privatización en este contexto, entiéndase el efecto de marcar como private y al mismo tiempo ocultar el miembro por medio de new en el subtipo. Para que quede más claro, echemos un vistazo al siguiente ejemplo (reusaré la versión de la sección 1.1).

Archivo PrivatizacionMiembroHeredado.cs:

En la línea 7 se declara como private el método heredado F (ya oculto a través de new). Cuando en la línea 12 la clase NuevaClase hereda de ClaseDerivada, se ha definido un método homónimo, el cual en su implementación invoca al método F; aquí hay que tener en cuenta que como en ClaseDerivada privatizamos este método, en este caso se invocará la versión declarada en ClaseBase.


1.3 Nota acerca del uso ambiguo de new

En [1] nos advierten sobre la ambigüedad de la construcción de C# new:
Ambigüedad new
Figura 1. Ambigüedad new [1].

2. Ejemplo de Ocultación de Campo Miembro

Este ejemplo demuestra la ocultación de un campo de instancia. Vayamos directo al ejemplo:

Archivo OcultacionCampo.cs:

No se espeficó el modificador new para ocultar de forma explícita y evitar que el compilador arroje la advertencia de ocultamiento no intencionado.

La modificación para el siguiente ejemplo, consiste en inclusión del modificador new para ocultar explícitamente el campo de instancia Counter.

Archivo OcultacionCampoNew.cs:



3. new versus override

Consideremos el siguiente ejemplo (adaptado de [1])  para demostrar la diferencia en el uso de estos dos construcciones.

Archivo DiferenciaNewOverride.cs:



> Prueba de ejecución.

Como se demuestra en la ejecución de prueba, con override [6] se sobreescribe completamente, y al mismo tiempo se toma posesión del control del método MetodoPrueba en la clase derivada. Esto se evidencia en la invocación b1.MetodoPrueba() (b1 es de tipo ClaseBase pero referencia un objeto de tipo Overrider).

Por otro lado, cuando usamos new no tomamos posesión del método MetodoPrueba en la invocación desde la sentencia b2.MetodoPrueba(). Aquí b2 es de tipo ClaseBase pero referencia a un objeto de tipo Hider; sin embargo, se invoca la versión de la primera, es decir, de ClaseBase.

[Nota: Para mayor información acerca de las diferencias diríjase a [7]].

Conclusiones

Comprendimos el mecanismo de ocultación de miembros de superclases a través del uso del modificador new. Reconocimos que la ausencia de este modificador hace que el compilador advierta sobre el uso no consentido de ocultación de miembro. Apreciamos a través de ejemplos cómo usar el modificador para métodos y campos de instancia (secciones 1.1 y 2). Finalmente, la diferencia entre new y override.

Glosario

- Ocultación
- Sobrescritura

Enlaces & Literatura

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2. 
[2]: 3.7.1.2 Hiding through inheritance (C#) - http://msdn.microsoft.com/en-us/library/aa691135(v=vs.71).aspx 
[3]: Polymorphism, Method Hiding and Overriding in C# - http://www.akadia.com/services/dotnet_polymorphism.html 
[4]: Method Hiding in C# - CodeProject - http://www.codeproject.com/Articles/18733/Method-Hiding-in-C 
[5]: new Modifier (C# Reference) - http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
[6]: Knowing When to Use Override and New Keywords (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/ms173153.aspx 
[7]: override (C# Reference) - http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx


H

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.