Clases Abstractas: Polimorfismo
Clases Abstractas: Polimorfismo
Clases Abstractas: Polimorfismo
Clases abstractas
Una clase abstracta, normalmente ocupa una posición alta en la jerarquía de clases que le
permite actuar como un depósito de métodos y atributos compartidos para las subclases de
nivel inmediatamente inferior. Las clases abstractas definen un tipo generalizado y sirven
solamente para describir nuevas clases.
Las clases abstractas no tienen instancias directamente. Se utilizan para agrupar otras clases
y capturar información que es común al grupo. Sin embargo, las subclases de clases abstractas
se corresponden a objetos del mundo real y pueden tener instancias. Las superclases que se
crean a partir de subclases con atributos y comportamientos comunes, y que sirven para
derivar otras clases que comparten sus características, son clases abstractas.
En C++ una clase abstracta tiene al menos una función miembro que se declara pero no se
define, su definición se realiza en la clase derivada. Estas funciones miembro se denominan
funciones virtuales puras, cuya definición formal es:
Virtual tipo nombreFuncion(argumentos) = 0;
Las siguientes reglas se aplican a las clases abstractas:
Una clase abstracta debe tener al menos una función virtual pura.
Una clase abstracta no se puede utilizar como un tipo de argumento o como un tipo
de retorno de una función aunque si un puntero a ella.
No se puede declarar una instancia de una clase abstracta.
Se puede utilizar un puntero o referencia a una clase abstracta.
Una clase derivada que no proporcione una definición de una función virtual pura,
también es una clase abstracta.
Cada clase (derivada de una clase abstracta) que proporcione una definición de todas
sus funciones virtuales es una clase concreta.
Solo esté permitido crear punteros a las clases abstractas y pasárselos a funciones.
FUNCIONES VIRTUALES
Si la palabra reservada virtual precede a la declaración de una función, esta función se llama
virtual y le indica al compilador que puede ser definida (implementado su cuerpo) en una
clase derivada y que en este caso la función se invocará directamente a través de un puntero.
Se debe calificar una función miembro de una clase con la palabra reservada virtual solo
cuando exista una posibilidad de que otras clases puedan ser derivadas de aquella.
Un uso común de las funciones virtuales es la declaración de clases abstractas y la
implementación del polimorfismo.
Ejemplo:
Una clase base Animal podría tener una función virtual come. La subclase Pez implementaría
come() de forma diferente que la subclase Lobo, pero se podría invocar a come() en cualquier
instancia de una clase referida como Animal, y obtener el comportamiento de come() de la
subclase específica.
Animal
Lobo Pez OtroAnimal
come() come() come()
Esto permitiría a un programador procesar una lista de objetos de la clase Animal, diciendo a
cada uno que coma (llamando a come()), sin saber qué tipo de animales hay en la lista.
Tampoco tendría que saber cómo come cada animal, o cuántos tipos de animales puede llegar
a existir.
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void come() { cout << "Yo como como un animal genérico.\n"; }
virtual ~Animal() {}
};
POLIMORFISMO
Ejemplo 1: Definir la clase padre persona y las subclases alumno y profesor y la función virtual
mostrar(), que muestre información personal de cada una de las clases hijas
#include <iostream>
using namespace std;
class persona {
private:
string nombre;
int edad;
public:
persona (string nom, int ed){
nombre = nom;
edad = ed;
}
virtual void mostrar(){
cout<<"nombre: "<<nombre<<endl;
cout<<"Edad: "<<edad<<endl;
}
};
persona *datos[3];
return 0;
}
Ejemplo 2: Definir una clase forma que sea una clase base abstracta que contenga la interfaz
hacia la jerarquía. Derive a dosDimensiones y tresDimensiones de la clase forma, que también
serán abstractas. Utilice una función print virtual para enviar a la salida el tipo y dimensiones
de cada figura. También incluye funciones virtual area y volume para que estos cálculos
puedan realizarse para los objetos de cada clase concreta de la jerarquía.
Escriba un programa controlador que pruebe la jerarquía de la clase forma.
#include <iostream>
#include <cmath>
using namespace std;
// clase forma
class forma {
public:
virtual double area() const { return 0.0; }
virtual double volumen() const { return 0.0; }
////////////////////////////////
// clase DosDimensiones ///
////////////////////////////////
// clase triangulo
class triangulo : public DosDimensiones {
double lado1, lado2, lado3;
public:
triangulo (double=0.0, double=0.0, double=0.0);
void fijar_triangulo(double, double, double);
virtual double area() const;
virtual void print() const;
};
return sqrt(s*(s-lado1)*(s-lado2)*(s-lado3));
}
// clase cuadrado
class cuadrado : public DosDimensiones {
double lado;
public:
cuadrado (double=0.0);
void fijar_cuadrado(double);
virtual double area() const;
virtual void print() const;
};
////////////////////////////////
// clase tresDimensiones /
////////////////////////////////
// clase cubo
class cubo : public tresDimensiones {
double lado;
public:
cubo(double=0.0);
void fijar_cubo(double);
virtual double area() const;
virtual double volumen() const;
virtual void print() const;
};
triangulo t(5.2,6.5,7.1);
virtualViaPointer (& t);
virtualViaReference (t);
cuadrado c(8.7);
virtualViaPointer (&c);
virtualViaReference (c);
cubo cub(8.3);
virtualViaPointer (&cub);
virtualViaReference (cub);
paralelepipedo p(4.5,6.7,9.2);
virtualViaPointer (&p);
virtualViaReference (p);
return 0;
}
Ejercicio:
1. Definir la clase objeto geométrico y las clases círculo y cuadrado que hereden las
coordenadas del centro de un círculo y de un cuadrado respectivamente. La clase
círculo deberá permitir calcular la longitud de la circunferencia y el área del círculo de
radio dado. La clase cuadrado debe permitir calcular el perímetro y el área del
cuadrado conociendo además un vértice del cuadrado.
Sugerencia: