Interfaces en C++: Dominando Clases Abstractas y Funciones Virtuales Puras
Una interfaz describe el comportamiento o capacidades de una clase C++ sin comprometerse a una implementación particular de esa clase.
Las interfaces de C++ se implementan usando clases abstractas y estas clases abstractas no deben confundirse con la abstracción de datos que es un concepto de mantener detalles de implementación separados de los datos asociados.
Una clase se hace abstracta declarando al menos una de sus funciones como función virtual pura. Una función virtual pura se especifica colocando "= 0" en su declaración de la siguiente manera:
class Caja {
public:
// función virtual pura
virtual double obtenerVolumen() = 0;
private:
double largo; // Largo de una caja
double ancho; // Ancho de una caja
double alto; // Alto de una caja
};
El propósito de una clase abstracta (a menudo referida como ABC) es proporcionar una clase base apropiada desde la cual otras clases pueden heredar. Las clases abstractas no pueden usarse para instanciar objetos y sirven solo como interfaz. Intentar instanciar un objeto de una clase abstracta causa un error de compilación.
Así, si una subclase de un ABC necesita ser instanciada, tiene que implementar cada una de las funciones virtuales, lo que significa que soporta la interfaz declarada por el ABC. Fallar en sobrescribir una función virtual pura en una clase derivada, e intentar instanciar objetos de esa clase, es un error de compilación.
Las clases que pueden usarse para instanciar objetos se llaman clases concretas.
Ejemplo de Clase Abstracta
Considera el siguiente ejemplo donde la clase padre proporciona una interfaz a la clase base para implementar una función llamada obtenerArea():
#include <iostream>
using namespace std;
// Clase base
class Forma {
public:
// función virtual pura proporcionando marco de interfaz.
virtual int obtenerArea() = 0;
void establecerAncho(int a) { ancho = a; }
void establecerAlto(int al) { alto = al; }
protected:
int ancho;
int alto;
};
// Clases derivadas
class Rectangulo: public Forma {
public:
int obtenerArea() {
return (ancho * alto);
}
};
class Triangulo: public Forma {
public:
int obtenerArea() {
return (ancho * alto) / 2;
}
};
int main(void) {
Rectangulo Rect;
Triangulo Tri;
Rect.establecerAncho(5);
Rect.establecerAlto(7);
// Imprimir el área del objeto.
cout << "Área total Rectángulo: " << Rect.obtenerArea() << endl;
Tri.establecerAncho(5);
Tri.establecerAlto(7);
// Imprimir el área del objeto.
cout << "Área total Triángulo: " << Tri.obtenerArea() << endl;
return 0;
}
Cuando el código anterior se compila y ejecuta, produce el siguiente resultado:
Área total Rectángulo: 35
Área total Triángulo: 17
Puedes ver cómo una clase abstracta definió una interfaz en términos de obtenerArea() y dos otras clases implementaron la misma función pero con diferente algoritmo para calcular el área específica de la forma.
Estrategia de Diseño
Un sistema orientado a objetos podría usar una clase base abstracta para proporcionar una interfaz común y estandarizada apropiada para todas las aplicaciones externas. Luego, a través de herencia desde esa clase base abstracta, se forman clases derivadas que operan de manera similar.
Las capacidades (es decir, las funciones públicas) ofrecidas por las aplicaciones externas se proporcionan como funciones virtuales puras en la clase base abstracta. Las implementaciones de estas funciones virtuales puras se proporcionan en las clases derivadas que corresponden a los tipos específicos de la aplicación.
Esta arquitectura también permite que nuevas aplicaciones se agreguen a un sistema fácilmente, incluso después de que el sistema haya sido definido.
Lenguaje C
- Estructuras vs Clases en C++: Guía práctica para desarrolladores embebidos
- Dominando clases y métodos abstractos en C#: Guía práctica
- Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
- Clases y Objetos en C++: Guía Práctica de Programación Orientada a Objetos
- Funciones y clases amigas en C++: dominando el control de acceso
- Dominando las plantillas de clase en C++: guía práctica
- Clases Abstractas en C#: Tutorial Práctico con Ejemplos de Código
- Clases y métodos abstractos en Java: Guía completa
- Domina Java: Entendiendo Objetos, Clases y Conceptos Básicos de POO
- Abstracción en Java Explicada: Simplifica Código y Mejora Legibilidad
- Entendiendo las Interfaces en Java: Definiciones, Usos y Buenas Prácticas