jueves, 12 de abril de 2007 14:28
jonas
Propiedades e interfaces, implementación implícita y explícita
Supongamos que tenemos
un par de clases que heredan de una clase base, bien, ¿qué ocurre si queremos
que esas clases incorporen la funcionalidad de otra clase base distinta? En C#
no podemos hacer eso porque solo disponemos de herencia simple y una de las
causas de esto puede ser para evitar la colisión de nombres, esta claro que
podemos echar mano de la interfaces pero… ¿y si necesitamos implementar esa
otra clase base para trabajar con algún atributo en nuestra nueva clase? Pues
tenemos una solución que en muchos casos nos podría resultar útil. C# nos
permite incorporar a las interfaces: métodos, propiedades, indizadores y
eventos.
Desde un punto de
vista generalista y en mi opinión, las propiedades las podemos ver como
atributos de una clase. Pues eso es lo que yo quise hacer, una interfaz con las
propiedades necesarias que posteriormente utilizaría para implementar mis
clases. Entonces solo queda definir la clase en cuestión y hacer que herede de
esa interfaz y pinchar sobre el nombre de la interfaz con el botón derecho del
ratón y nos saldrá una opción para implementar dicha interfaz que nos genererará el esqueleto
de lo que la interfaz contenga, así solo tendremos que darle la funcionalidad.
Esta implementación puede ser de forma implícita o explícita.

Pues esto fue algo en
lo que no me fijé y le di a implementar de forma explícita y la sorpresa me la
lleve al intentar usar esa propiedad. La diferencia la podemos ver con un
ejemplo, supongamos que tenemos una clase Trabajador que implementa una
interfaz llamada IDesarrollador que contiene una propiedad Name:

Ahora de forma
explicita:

La diferencia entre
implementar una interfaz de forma implícita o explícitamente es que esta última
elimina el modificador public de la propiedad y antepone al nombre el nombre de
la interfaz seguida de un punto. ¿Entonces por qué el intellisense de visual
studio no me muestra la propiedad Name?
La implementación
explicita de una interfaz mata dos pájaros de un tiro. Por un lado, como una
clase puede implementar múltiples interfaces evitamos la colisión de nombres.
Por otro lado, tenemos la ocultación de nombres, en la imagen anterior se ve
como no tenemos acceso a la propiedad Name, para poder hacer uso de esa
propiedad tendríamos que hacerle un cast al objeto unTrabajador para que fuese
del tipo interfaz IDesarrollador. Esto permite que un objeto tenga una
funcionalidad diferente dependiendo del contexto en el que se encuentre.
Supongamos que esa
interfaz IDesarrollador proporciona una funcionalidad bien diferencia de la que
por definición proporciona la clase Trabajador, entonces en un principio
podemos no querer la funcionalidad que proporciona la interfaz IDesarrollador,
pues teniendo una implementación explicita de dicha interfaz, su funcionalidad
permanecerá oculta a un objeto de la clase Trabajador y solo cuando convirtamos
a ese objeto al tipo IDesarrollador podremos acceder a la propiedad Name. Esto
puede ser muy útil para no mezclar espacios de nombres, para intentar tener una
visión más clara de un objeto o separar los miembros más usados de los menos
comunes, lo que se nos ocurra…
PD: Al implementar la
interfaz de forma explicita y modificar el código para que quede como si fuese
una implementación implícita, visual studio genera un error en tiempo de
compilación, así que lo mejor es borrar e implementar de nuevo la interfaz,
pero esta vez de manera implícita... ¿bug?.