Menu
Coddy logo textTech

El concepto de interfaz

Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 40 de 61.

Hasta ahora, nuestros structs han mezclado datos y comportamiento — un nombre junto a un puntero de función, por ejemplo. ¿Pero qué pasaría si un struct contuviera solo punteros de función? Esto crea algo poderoso: una interfaz.

Una interfaz define qué operaciones están disponibles sin especificar cómo funcionan. Es un contrato que dice "cualquier objeto que implemente esta interfaz debe proporcionar estas funciones".

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

La estructura ILogger no contiene nada más que un puntero a función. No tiene datos propios; describe puramente el comportamiento. El prefijo «I» es una convención común que indica que se trata de una interfaz.

Cualquier código que acepte un ILogger no le importa a dónde va el mensaje de registro. Podría imprimir en la consola, escribir en un archivo o enviar datos a través de una red. El llamador simplemente sabe que puede llamar a log:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // No sabemos CÓMO registra
}

Esta separación es la esencia del polimorfismo. La función process funciona con cualquier implementación de logger — puedes intercambiar comportamientos sin cambiar el código de la función. En la siguiente lección, crearás implementaciones concretas que cumplan con este contrato de interfaz.

challenge icon

Desafío

Fácil

Vamos a construir una interfaz ICalculator — una estructura que contiene solo punteros a funciones, definiendo qué operaciones debe soportar cualquier calculadora sin especificar cómo funcionan.

Crearás dos archivos para organizar tu código:

  • calculator.h: Define tu interfaz aquí. Crea un tipo de puntero a función llamado BinaryOp que reciba dos parámetros int y devuelva un int. Luego, define una estructura ICalculator que contenga solo dos punteros a funciones: operate (de tipo BinaryOp) y describe (un puntero a función que no recibe parámetros y no devuelve nada). Esta estructura es puramente una interfaz — no contiene datos, solo comportamiento.
  • main.c: Incluye tu cabecera e implementa funciones concretas que puedan cumplir con la interfaz:
    • add — devuelve la suma de dos números enteros
    • multiply — devuelve el producto de dos números enteros
    • describe_add — imprime Addition
    • describe_multiply — imprime Multiplication
    Luego, crea una instancia de ICalculator, conéctala según la entrada y úsala para realizar un cálculo.

Tu programa recibirá tres entradas: dos enteros y un código de operación (1 para suma, 2 para multiplicación).

Basándote en el código de operación, conecta tu ICalculator con el par de funciones apropiado. Luego, llama a describe a través de la interfaz para imprimir el nombre de la operación, seguido de una llamada a operate para calcular e imprimir el resultado.

Ejemplo de salida cuando las entradas son 5, 3 y 1:

Addition
8

Ejemplo de salida cuando las entradas son 4, 7 y 2:

Multiplication
28

La idea clave es que tu estructura ICalculator define un contrato — cualquier código que la use sabe que puede llamar a describe y operate, sin saber qué funciones específicas están conectadas. Recuerda usar guardas de inclusión en tu archivo de cabecera.

Hoja de referencia

Una interfaz es una estructura que contiene solo punteros a funciones, definiendo qué operaciones están disponibles sin especificar cómo funcionan.

Definiendo una interfaz:

typedef void (*LogFunc)(const char* message);

typedef struct {
    LogFunc log;
} ILogger;

El prefijo "I" es una convención común que indica que se trata de una interfaz. La estructura no contiene datos; puramente describe el comportamiento.

Usando una interfaz:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // No sabemos CÓMO registra
}

Esta separación permite el polimorfismo: la función trabaja con cualquier implementación de la interfaz, lo que le permite intercambiar comportamientos sin cambiar el código de la función.

Pruébalo tú mismo

#include <stdio.h>
#include "calculator.h"

// TODO: Implementar la función add
// Devuelve la suma de dos enteros


// TODO: Implementar la función multiply
// Devuelve el producto de dos enteros


// TODO: Implementar la función describe_add
// Imprime "Addition"


// TODO: Implementar la función describe_multiply
// Imprime "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: Crear una instancia de ICalculator
    
    
    // TODO: Basándose en op_code (1 para add, 2 para multiply),
    // conectar la calculadora con las funciones apropiadas
    
    
    // TODO: Llamar a describe a través de la interfaz
    
    
    // TODO: Llamar a operate a través de la interfaz e imprimir el resultado
    
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming