Uniddad 5 Fun nciones Viirtualles y Polim morfissmo Introoducción. Ambbos conceptoos están estrrechamentee ligados conn el tema dee la herencia y son exteensiones que trabajan t en las clases base y derivaadas de unaa manera parrticular y ess lo que se desarrrollará en eesta unidad.. 5.1. Funciones F V Virtuales Una función virrtual es mieembro de unna clase quee se declaraa dentro de una clase base b y se redeffine en unaa clase derrivada. Paraa crear unaa función virtual v hay que preceeder a la declaaración de la l función la l palabra clave c virtuaal. Debe tenner el mism mo tipo y nu umero de parám metros y deevolver el mismo m tipo. Cadaa redefinicióón de la fuunción virtuual en una clase derivaada expresaa el funcion namiento especcifico de laa misma conn respecto a esa clase derivada. Cuando C se rredefine unaa función virtual en una cllase derivad da NO es neecesaria la ppalabra virtuual. Ejem mplo: #incllude<iostreaam.h> #incllude<stdio.hh> #incllude<conio..h> classs base{ publiic: int i; base ( intt x ){i =x;} virtual void v func( ) (){cout<<ii<<"\n";} }; classs derivada1:public basee{ publiic: derivadaa1(int x):basse(x){}; void funcc(){ cout << <i*i<<"\n";} }; classs derivada2:public basee{ publiic: U.S..B. – Progra ramación IIII Páágina 54 derivada2(int x):base(x){}; void func(){cout<<i+i;} }; void main() { base obj1(10); derivada1 obj2(10); derivada2 obj3(10); obj1.func(); obj2.func(); obj3.func(); getch(); } 5.2. Polimorfismo Este concepto deriva del griego poli que significa muchos y morfos que quiere decir forma, luego esto nos da la idea de que la clase tenga la posibilidad de que sus métodos o propiedades se comporten de manera diferente, y de esa manera se cuenta con múltiples formas. Luego, el polimorfismo hace posible que se tengan comportamientos diferentes, asociados a diferentes objetos, los cuales pueden compartir el mismo nombre, al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. Por ejemplo, si trabajamos con figuras geométricas, tales como: un círculo y un cuadrado los cuales se dibujan de diferente forma y tienen diferentes áreas. Usando el polimorfismo se puede enviar a cada una de las formas el mismo mensaje; así, si envío el mensaje Dibuja al objeto circulo este realizará la acción debida dibujando un círculo. Otro ejemplo se da si se cuando se envía un mensaje "+" a un objeto entero que significaría suma, mientras que para un objeto string significaría concatenación, unir strings uno seguido al otro. O dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en "tiempo de ejecución", esta última característica se llama asignación tardía o asignación dinámica. El Polimorfismo se puede aplicar tanto a funciones como a operadores. En síntesis el polimorfismo significa que objetos similares pueden responder al mismo mensaje de diferentes maneras. U.S.B. – Programación III Página 55 5.3. Ejemplo Completo de Polimorfismo /* EJEMPLO DE POLIMORFISMO Y FUNCIONES VIRTUALES DONDE FIGURA ES LA CLASE BASE Y LAS CLASES DERIVADAS SON CIRCULO Y RECTANGULO */ #include <stdio.h> #include <graphics.h> #include <iostream.h> #include <stdlib.h> #include <conio.h> #include <math.h> #include <dos.h> #include <ctype.h> #include <string.h> #define L(t) ((t>='A'&&t<='Z')||(t>='a'&&t<='z')||t==' '||t=='.'||(t>='0'&&t<='9')||t==','||t==';')?1:0 //Prototipos de funciones de modo gráfico para lectura de valores void lee(char *msg, int x, int y, char *cad); void cursor(int x, int y, int pos); // Definicion de la clase figura Plana class FIGURA { protected: int col; // Color de la figura public: FIGURA(){ col = BLUE;} void elcolor(int c) { col = c; } virtual void dibuja( ){ } //Clase Virtual que indica el polimorfismo virtual void area( ){ } virtual void datos( ){ } }; U.S.B. – Programación III Página 56 // Definicion de la clase CIRCULO que se hereda de FIGURA class CIRCULO:public FIGURA { int xc, yc, r; float pi; public: CIRCULO(){ xc= getmaxx()/2; yc= getmaxy()/2; r=50; pi = 3.14;} void dibuja(){setcolor(col); circle(xc,yc,r);} void datos(){ char buffer[30]; outtextxy(10,10,"Introduzca los datos para del circulo:"); lee("X:", 10, 20,buffer); xc = atoi(buffer); //Convierte a numero entero lee("Y:", 10, 30,buffer); yc = atoi(buffer); lee("Radio:", 10, 40,buffer); r = atoi(buffer); } void area(); }; void CIRCULO::area( ) { char buffer[30]; float res = 2*pi*r; sprintf(buffer,"El area del circulo es de: %.2f",res); outtextxy(10,70,buffer); } //Realiza la derivacion de la clase Rectangulo void modografico() { int gd=DETECT, gm, error; initgraph(&gd,&gm,"c:/borlandc/bgi"); error = graphresult(); if (error!= grOk) // ocurrio un error { cout<<"ERROR: "<<grapherrormsg(error)<<endl; cout<<"Presione alguna tecla para continuar..."; getch(); exit(1); //Termina el programa } else cleardevice(); //Borra la pantalla } U.S.B. – Programación III Página 57 void lee(char *msg, int x, int y,char *cad) { char t,d[7];unsigned int pos=0,c=getcolor(); strcpy(cad,""); setcolor(14); outtextxy(x,y,msg); setcolor(15); x+=strlen(msg)*8+20; setfillstyle(1,0); do{ cursor(x,y,pos); t=getch(); sprintf(d,"%c",t); if((L(t))&&(t!=13)) { outtextxy(x+(pos*8),y,d); cad[pos]=t; pos++; } }while(t!=13); cad[pos]='\x0'; setcolor(c); } void cursor(int x, int y, int pos) { int i,color=getcolor(); do{ setcolor(7); setwritemode(1); line(x+pos*8,y+9,x+pos*8+7,y+9); for(i=1;i<50;i++); line(x+pos*8,y+9,x+pos*8+7,y+9); setcolor(color); }while(!kbhit()); } void main( ) { modografico( ); float areac; CIRCULO c; U.S.B. – Programación III Página 58 c.dibuja(); getch(); cleardevice(); c.datos(); c.area(); c.dibuja(); getch(); } Ejercicios Propuestos 1. Implemente el polimorfismo en las clase Mueble, para el cual cree tres clases derivadas. 2. En la clase base Animal y las clases derivadas: Mamifero y Oviparo implemente el polimorfismo U.S.B. – Programación III Página 59