Interfaces en C++: Cómo declararlas sin volverse loco

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Interfaces en C++: Guía para quienes están cansados de buscar en Google

\n\n

Si 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\n

En 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\n

En 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\n

Recuerda 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
\n\n

Para una interfaz pura, usamos exactamente la primera opción: sin lógica, solo declaraciones.

\n\n

Cómo declarar una interfaz pura: sintaxis básica

\n\n

Aquí tienes un ejemplo mínimo de una interfaz para una figura geométrica:

\n\n
class 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\n

Observa 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.

\n\n

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
\n\n

Implementación de la interfaz: de las palabras a la acción

\n\n

Ahora escribamos una clase que implemente nuestra interfaz IShape. Que sea un círculo:

\n\n
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\n

La 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".

\n\n

Polimorfismo en acción

\n\n

Ahora viene lo interesante: podemos trabajar con diferentes figuras a través de una interfaz única:

\n\n
void 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\n

La 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