Interfaces en C++: Guía para quienes están cansados de buscar en Google
\n\nSi alguna vez has programado en Java o C#, y luego pasaste a C++, seguramente te habrás preguntado: "¿Dónde está la palabra clave interface?". Spoiler: no existe. En C++, las interfaces se implementan de otra manera — a través de clases abstractas. Y esto no es un error, sino una característica que ofrece una flexibilidad increíble.
\n\nEn Stack Overflow, la pregunta "How do you declare an interface in C++?" acumula miles de visitas. Esto significa que incluso los desarrolladores experimentados a veces se confunden. Hoy vamos a aclarar de una vez por todas cómo declarar una interfaz en C++, para que tu código sea limpio y el compilador esté contento.
\n\n¿Qué es una interfaz en C++? (Spoiler: es una clase abstracta)
\n\nEn la POO clásica, una interfaz es un contrato. La clase que implementa la interfaz está obligada a proporcionar la implementación de todos sus métodos. En C++, este rol lo cumple una clase abstracta — una clase que contiene al menos una función virtual pura (pure virtual function).
\n\nRecuerda la regla principal:
\n- \n
- Interfaz = clase donde todos los métodos son virtuales puros. \n
- Clase abstracta = clase donde al menos un método es virtual puro (pero puede tener métodos normales con implementación). \n
Para una interfaz pura, usamos exactamente la primera opción: sin lógica, solo declaraciones.
\n\nCómo declarar una interfaz pura: sintaxis básica
\n\nAquí tienes un ejemplo mínimo de una interfaz para una figura geométrica:
\n\nclass IShape {\npublic:\n virtual double area() const = 0; // Función virtual pura\n virtual double perimeter() const = 0; // Otra más\n virtual ~IShape() {} // Destructor virtual — ¡obligatorio!\n};\n\nObserva el = 0 al final de la declaración. Esa es la marca mágica de "virtual puro". Este método no tiene cuerpo (implementación) en la clase base.
Puntos clave:
\n- \n
- Prefijo I en el nombre de la clase — una convención no oficial para interfaces (I = Interface). No es obligatorio usarlo, pero facilita la lectura del código. \n
- Destructor virtual obligatorio. Si eliminas un objeto a través de un puntero a la interfaz, sin un destructor virtual el comportamiento será indefinido (léase: el programa fallará). \n
- Todos los métodos son public — la interfaz debe ser accesible para ser llamada desde fuera. \n
Implementación de la interfaz: de las palabras a la acción
\n\nAhora escribamos una clase que implemente nuestra interfaz IShape. Que sea un círculo:
class Circle : public IShape {\nprivate:\n double radius;\npublic:\n explicit Circle(double r) : radius(r) {}\n\n double area() const override {\n return 3.14159 * radius * radius;\n }\n\n double perimeter() const override {\n return 2 * 3.14159 * radius;\n }\n};\n\nLa palabra clave override (C++11 y posteriores) no es obligatoria, pero es muy recomendable. Obliga al compilador a verificar que realmente estás sobrescribiendo un método virtual de la clase base. ¿Te equivocaste en el nombre? El compilador dirá: "¡Error! Ese método no existe en la interfaz".
Polimorfismo en acción
\n\nAhora viene lo interesante: podemos trabajar con diferentes figuras a través de una interfaz única:
\n\nvoid printShapeInfo(const IShape& shape) {\n std::cout << "Area: " << shape.area() << "\\n";\n std::cout << "Perimeter: " << shape.perimeter() << "\\n";\n}\n\nint main() {\n Circle c(5.0);\n printShapeInfo(c); // ¡Funciona!\n return 0;\n}\n\nLa función printShapeInfo recibe una referencia a IShape. No le importa qué objeto se le pase — un círculo, un cuadrado o un triángulo. Mientras implementen la interfaz, todo funcionará. Esto es polimorfismo
Blogs
Book Recommendations
Leer también
Escritura de documentación para un proyecto JavaScript: de la A a la Z
Errores comunes en Python y cómo solucionarlos: De IndentationError a RecursionError
Swift en 2025: por dónde empezar a aprender en la práctica
Trabajo con bases de datos en PHP: PostgreSQL y MongoDB en la práctica
Arquitectura Event-driven en Java: creando sistemas reactivos