Club.NET Almería

Plataforma .NET de Ingenieros/Ingenieros Técnicos en Informática de Almería
¡Bienvenid@ a Club.NET Almería! Iniciar sesión | ÚNETE a la web | Ayuda
en Buscar
Principal Blogs Foros Imágenes Descargas

Polimorfismo Extremo

Último artículo 02-21-2007, 13:28 escrito por jaberme. 1 respuestas.
Ordenar mensajes: Anterior Siguiente
  •  02-21-2007, 13:20 677

    Polimorfismo Extremo

    Veamos el siguiente supuesto: Tienes una clase base, de la que heredan digamos siete clases diferentes.

    Tienes un vector en el que deseas almacenar objetos que sean del mismo tipo de una de las siete clases derivadas (y sólo de esa), pero en tiempo de programación no sabes a priori de cuál de los siete tipos se trata.

    O bien, simplemente quieres crear un objeto de un tipo X, pero a priori no sabes qué tipo X es (entonces puedes considerar que X es una clase derivada de Object, y por tanto se aplica también el supuesto anterior) 

    ¿Cómo entonces puedes crear N objetos del tipo elegido EN TIEMPO DE EJECUCIÓN si a priori no sabías cuál de ellos es?

    La respuesta se puede conseguir en el namespace System.Reflection:

    La línea de código

    AppDomain.CurrentDomain.CreateInstanceAndUnwrap( ObjetoDerivado.GetType().Assembly.FullName, ObjetoDerivado.GetType().FullName ); 

    Nos crea un objeto perteneciente al ensamblado al que pertenece el objeto "ObjetoDerivado", que puede ser de cualquier clase perteneciente a ese ensamblado, y cuyo nombre se puede obtener también fácilmente. El método GetType() nos devuelve un objeto del tipo Type que podemos utilizar para obtener información acerca la clase a la que pertenece un objeto determinado, así como su "clase Base" en caso de herencia.

    Como el método "CreateInstanceAndUnwrap" nos devuelve un objeto del tipo "object", debemos hacer un cast explícito si queremos guardar el objeto en un array polimórfico de la clase Base.


    Ejemplo:
    Tenemos una clase base Cromosoma, y para el laboratorio de Ingeniería Genética en el que trabajamos tenemos CromoPerro, CromoMono y CromoLoro. Todos ellos son clases derivadas de Cromosoma, es decir, que su declaración sería algo así como:

     public class CromoPerro: Cromosoma{ ... }

    En cualquier momento, en tiempo de ejecución, podemos necesitar guardar 20 Cromosomas del tipo CromoPerro en una probeta (Un array de toda la vida). En tiempo de diseño, no sabemos "a priori" qué cromosomas se pueden guardar en la probeta. Pueden ser CromoPerros, CromoMonos o CromoLoros. Para solucionarlo, decidimos utilizar polimorfismo y declarar un array así:

    Cromosoma[] probeta = new Cromosoma[20];

    A continuación, un sistema automatizado decide que necesita guardar elementos de la clase CromoPerro para realizar experimentos de mutación con cada uno de ellos. Crea un Cromosoma del tipo CromoPerro

    Cromosoma muestra=new CromoPerro();

    Y a continuación pulsa el botón "replicar Cromosoma en probeta". El programa no sabe a priori qué tipo de cromosomas se guardan en la "muestra" (bueno, en este sencillo ejemplo sí), entonces para obtener las 20 réplicas del cromosoma hace lo siguiente:


    for(int i=0;i<20;i++)  probeta[i] = (Cromosoma)AppDomain.CurrentDomain.CreateInstanceAndUnwrap( muestra.GetType().Assembly.FullName, muestra.GetType().FullName );

    Una vez realizado, podemos comprobar que los 20 cromosomas de la probeta son del tipo CromoPerro con el siguiente código:

    for(int i=0;i<20;i++)  MessageBox.Show(probeta[i].getType().ToString());

    El cual nos mostrará 20 mensajes diciéndonos lo siguiente: NameSpace.CromoPerro


    Utilidad Principal: A lo largo del ciclo de vida de un programa, en caso de utilizar mucho la herencia y polimorfismo, nunca sabes cuándo puedes añadir nuevas clases derivadas. Utilizando técnicas tradicionales, eso significa que tendrías un switch para identificar la clase derivada a la que pertenece un objeto (normalmente identificado mediante un flag), y por tanto, cada vez que necesites crear/guardar en un lugar objetos cuyo tipo no conoces a priori, pero necesitas que sean del mismo tipo original, entonces este fragmento de código te evitará muchos dolores de cabeza con una gran cantidad de "switch"es.
    Tal vez sea un snippet de uso demasiado específico, pero desde luego, encontrar esto en la red es una tarea harto complicada (básicamente, cuando me hizo falta buscarlo no lo encontraba en ningún sitio :P)

    Comentarios, dudas, erratas, etc son bienvenidas :) 


    Fullbyte Alchemist
    Archivado en: ,,
  •  02-21-2007, 13:28 679 en respuesta a 677

    Re: Polimorfismo Extremo

    Java también hacía esto hace mucho, mira aqui:

    http://java.sun.com/developer/technicalArticles/ALT/Reflection/ (ojo a la fecha: 1998)

    http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html (incorporado desde JDK 1.0)

     

    Eso si, en Java la herencia múltiple hay que simularla con interfaces.


    José Antonio Álvarez Bermejo.
    - - - disclaimer - - -
    Las opiniones son como el olor corporal, a cada uno le gusta el suyo. No te esfuerces en oponerte a mi opinión por que esa es tú opinión y a mi me trae sin cuidado.
Ver como una fuente de noticias RSS en XML
Ofrecido por Community Server (Personal Edition)