Tema: Funciones Virtuales y Polimorfismo.

Anuncio
Programación II. Guía 10
1
Facultad:
Ingeniería
Escuela:
Computación
Asignatura: Programación II
Tema: Funciones Virtuales y Polimorfismo.
Objetivos Específicos
ƒ
Comprender que es ligadura e identificar sus tipos.
ƒ
Describir el concepto de polimorfismo
ƒ
Utilizar las funciones virtuales para aplicar el polimorfismo en C++.
ƒ
Definir funciones virtuales.
Materiales y Equipo
• Computadora con el software DevC++.
• Guía Número 10.
Introducción Teórica
Ligadura.
Representa una conexión entre una entidad y sus propiedades. Si la propiedad se limita a
funciones, ligadura es la conexión entre la llamada a función y el código que se ejecuta tras la
llamada. Desde el punto de vista de atributos, la ligadura es el proceso de asociar un atributo a
un nombre.
El momento en que un atributo o función se asocia con sus valores o funciones se denomina
tiempo de ligadura.
Clasificación de la ligadura.
La ligadura se clasifica según sea el tiempo o momento de la ligadura en:
a) Ligadura Estática: Se produce antes de la ejecución (durante la compilación).
b) Ligadura Dinámica: ocurre durante el tiempo de ejecución.
2
Programación II, Guía 10
Funciones Virtuales.
Una función virtual es una función miembro pública o protegida de una clase base que puede
ser redefinida en cada una de las clases derivadas de esta, y una vez redefinida puede ser
accedida mediante un puntero o referencia a la clase base.
Esta se declara colocando la palabra clave virtual antes de la declaración de la función
miembro perteneciente a la clase base, así:
virtual <tipo de dato> <nombre de la función> (lista de parámetros);
Polimorfismo.
La utilización de clases derivadas y funciones virtuales es frecuentemente denominada
programación orientada a objetos. Además, la facultad de llamar a una variedad de funciones
utilizando exactamente el mismo medio de acceso, proporcionada por funciones virtuales, es a
veces denominada polimorfismo.
Polimorfismo significa “la facultad de asumir muchas formas”, refiriéndose a la facultad de
llamar a muchas funciones diferentes con una sola sentencia.
En un lenguaje orientado a objetos, el polimorfismo es la propiedad por la que un mensaje
puede significar cosas diferentes dependiendo del objeto que lo recibe. La razón por la que el
polimorfismo es útil se debe a que proporciona la capacidad de manipular instancias de clases
derivadas a través de un conjunto de operaciones definidas en su clase base. Cada clase
derivada puede implementar las operaciones definidas en la clase base.
El polimorfismo adquiere su máxima potencia cuando se utiliza en unión con la herencia.
Reglas para utilizar Polimorfismo.
1. Crear una jerarquía de clases con las operaciones importantes definidas por las funciones
miembros declaradas como virtuales en la clase base.
2. Las implementaciones específicas de las funciones virtuales se deben hacer en las clases
derivadas. Cada clase derivada puede tener su propia versión de las funciones.
3. Las instancias de las clases se manipulan a través de referencias o un puntero. Este
mecanismo es la ligadura dinámica y es la esencia del uso polimórfico en C++.
Clases Abstractas.
Una clase abstracta es una clase que se define con el propósito de establecer bases
conceptuales sobre las cuales se definirán otras clases, mismas que podrán ser clases
concretas. Es decir, una clase abstracta no se usará directamente en la solución de un
Programación II. Guía 10 3
problema, sino que formará parte del diseño conceptual de la solución. Por lo tanto, en el
programa no se crearán instancias (objetos) de las clases abstractas. Sin embargo, cabe
destacar que las clases derivadas sí heredan sus miembros.
En una clase abstracta pueden incluirse métodos virtuales que requieren ser especificados en
las clases derivadas. Es decir, métodos a los que se les asignará el contenido en cada clase
derivada. Estos métodos reciben el nombre de métodos virtuales puros y se inicializan con el
valor de cero. Si las clases derivadas no los especifican, entonces se producirá un error.
Procedimiento
Ejemplo 1 – Funciones Virtuales.
El siguiente ejemplo utiliza una clase llamada Figuras como Clase base y se implementan dos
clases derivadas Rectángulo y Triangulo, como se muestra en la siguiente jerarquía de
herencia:
Figuras
Triángulo
Rectángulo
#include <iostream>
using namespace std;
class Figuras
{ protected:
char identificar[25];
float area;
public:
// Definiendo las funciones virtuales en la clase base
virtual void Calcular_Area();
virtual void Dibujar_Figura();
virtual void Identificar();
};
// Cuando se definen las funciones no es necesario utilizar virtual
void Figuras :: Calcular_Area( )
{
}
void Figuras :: Dibujar_Figura( )
{ cout << "No hay dibujo disponible..." << endl;
}
4
Programación II, Guía 10
void Figuras :: Identificar( )
{ cout << endl << "Nombre Figura: " << identificar << endl;
cout << "El Area es: " << area << endl;
}
class Rectangulo : public Figuras
{ protected:
float base;
float altura;
// Definición de la clase derivada Rectángulo
public:
Rectangulo(float b, float a);
void Calcular_Area();
void Dibujar_Figura();
void Identificar();
};
Rectangulo :: Rectangulo(float b, float a)
{ base = b;
altura = a;
strcpy(identificar,"Rectangulo");
}
void Rectangulo :: Calcular_Area( )
{ area = (base * altura);
}
void Rectangulo :: Dibujar_Figura( )
{ cout << endl;
cout << "********** " << endl;
cout << "*
* " << endl;
cout << "*
* altura = " << altura << endl;
cout << "*
* " << endl;
cout << "********** " << endl;
cout << " Base = " << base << endl;
}
void Rectangulo :: Identificar( )
{ Figuras::Identificar();
cout << endl << "Sus datos son: " << endl;
}
class Triangulo : public Figuras
{ protected:
float base;
float altura;
public:
Triangulo(float b, float a);
void Calcular_Area();
void Dibujar_Figura();
void Identificar();
};
// Definición de la clase derivada Triángulo
Programación II. Guía 10 5
Triangulo :: Triangulo(float b, float a)
{ base = b;
altura = a;
strcpy(identificar,"Triangulo");
}
void Triangulo :: Calcular_Area( )
{ area = ((base * altura) / 2);
}
void Triangulo :: Dibujar_Figura( )
{ cout << " **
" << endl;
cout << " * * " << endl;
cout << " *
* " << endl;
cout << " *
* altura = " << altura << endl;
cout << "*
* " << endl;
cout << "********** " << endl;
cout << " Base = " << base << endl;
}
void Triangulo
:: Identificar( )
Ejemplo
2:
{ Figuras::Identificar();
Se muestra un ejemplo de Herencia Múltiple. Se realiza la implementación de la jerarquía
cout << endl << "Sus datos son: " << endl << endl;
de} clases mostrada en la siguiente figura:
int main()
{ Rectangulo Rec(10,10);
Triangulo Tri(5,5);
Rombo Rom(7,3);
// Implementando objeto de la clase rectángulo
Rec.Calcular_Area();
Rec.Identificar();
Rec.Dibujar_Figura();
//Implementando objeto de la clase Triangulo
Tri.Calcular_Area();
Tri.Identificar();
Tri.Dibujar_Figura();
system("pause > nul");
return 0;
}
Ejemplo 2 – Polimorfismo.
La forma más adecuada de usar el polimorfismo es a través de punteros, el siguiente ejemplo
utiliza un arreglo de objetos para poder definir el concepto. Utilizaremos el ejemplo No. 1.
Modificar la función main del programa anterior por el siguiente código:
6
Programación II, Guía 10
int main()
{ Figuras * arreglobj[5];
// Se crea un arreglo de objetos de la clase Figuras
// Ahora se crearan 5 objetos para luego ser utilizados por el arreglo de objetos
Rectangulo Rec1(15,15);
Rectangulo Rec2(20,20);
Triangulo Tri1(3,5);
Triangulo Tri2(2,6);
Triangulo Tri3(5,5);
/* Cada objeto definido anteriormente será un elemento del arreglo donde cada
elemento es un puntero a un objeto Figuras, aquí se utiliza el concepto de polimorfismo.
Se hace referencia a cada objeto creado */
arreglobj[0] = &Rec1;
arreglobj[1] = &Rec2;
arreglobj[2] = &Tri1;
arreglobj[3] = &Tri2;
arreglobj[4] = &Tri3;
// Se calcularán las áreas, se identificará cada objeto y se visualizará su información
for(int i = 0; i < 5; i++)
{ arreglobj[i] -> Calcular_Area( );
arreglobj[i] -> Identificar( );
arreglobj[i] -> Dibujar_Figura( );
cout << "----------------------------"<<endl;
system("pause");
}
cout << endl << " FIN DE LA DEMOSTRACION " << endl;
system("pause > nul");
return 0;
}
Nota: Un puntero a un objeto de la clase base puede ser utilizado para direccionar un
objeto de cualquiera de sus clases derivadas, lo cual permitirá invocar automáticamente a
través de este puntero a una función declarada virtual correspondiente a la clase del
objeto apuntado.
Análisis de Resultados
Ejercicio 1:
Agregar una nueva derivación de Figuras con la clase Rombo, las propiedades que tendrá el
rombo son diagonal mayor y diagonal menor, el área del rombo es:
Programación II. Guía 10 7
Área Rombo = (Diagonal Mayor * Diagonal Menor) / 2
Realice las modificaciones necesarias al ejemplo No. 1, de tal manera que se construya una
solución para la jerarquía de clases mostrada en la siguiente figura:
Figuras
Triángulo
Rectángulo
Rombo
Ejercicio 2:
Considere la siguiente jerarquía de herencias:
Biblioteca
Libros
Revistas
Artículos
Definir las clases. Considerar todas las propiedades y funciones necesarias para una
implementación completa haciendo uso de funciones virtuales y polimorfismo. Decidir que
atributos y métodos incluir en cada clase de tal manera que su programa pueda a través de un
menú realizar las siguientes acciones:
a) Crear objetos de cualquier tipo, solicitando los datos al usuario.
b) Visualizar un objeto en particular, con todos sus atributos.
c) Salir de la aplicación.
Ser creativos con la solución, es decir, agregar más opciones al menú.
El menú deberá estar siempre activo, en la misma posición en pantalla, hasta que el usuario
seleccione la opción salir. El programa debe estar debidamente comentado.
Investigación Complementaria
Considere la siguiente jerarquía de herencias:
8
Programación II, Guía 10
Figura
Equilátero
Triangulo
Rectángulo
TRectángulo
Cuadrado
A continuación se muestra la declaración de la Clase “Figura”
#include <iostream>
using namespace std;
class Figura
{
public:
Figura ( ) { };
// Constructor por defecto
virtual float CalcularArea( ) = 0;
virtual float CalcularPerimetro( ) = 0;
};
La clase “Figura” se usará como clase base para declarar las clases derivadas: Triangulo,
Rectangulo y Cuadrado. La clase base es una clase abstracta.
Diseñar una implementación que simule la jerarquía mostrada.
Considerar los atributos y métodos necesarios en cada clase de tal manera que su programa
pueda a través de un menú realizar las siguientes acciones:
a) Crear objetos de cualquier tipo, solicitando los datos al usuario.
b) Calcular el área de cualquier objeto seleccionado por el usuario.
c) Calcular el perímetro de cualquier objeto seleccionado por el usuario.
d) Salir de la aplicación.
El menú deberá estar siempre activo, en la misma posición en pantalla, hasta que el usuario
seleccione la opción salir. El programa debe estar debidamente comentado.
Programación II. Guía 10 9
Guía 10: Funciones
Polimorfismo.
Virtuales
Hoja de cotejo:
y
Alumno:
Máquina No:
Docente:
GL:
10
Fecha:
EVALUACIÓN
%
CONOCIMIENTO
Del 20
al 30%
APLICACIÓN
DEL
CONOCIMIENTO
Del 40%
al 60%
1-4
5-7
8-10
Conocimiento
deficiente de
los fundamentos
teóricos
Conocimiento
y explicación
incompleta de
los
fundamentos
teóricos
Conocimiento
completo y
explicación
clara de los
fundamentos
teóricos
No tiene
actitud
proactiva.
Actitud
propositiva y
con
propuestas no
aplicables al
contenido de
la guía.
Tiene actitud
proactiva y
sus
propuestas
son
concretas.
ACTITUD
Del 15%
al 30%
TOTAL
100%
Nota
Descargar