Menu
Coddy logo textTech

O Conceito de Interface

Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 40 de 61.

Até agora, nossas structs misturaram dados e comportamento — um nome ao lado de um ponteiro de função, por exemplo. Mas e se uma struct contivesse apenas ponteiros de função? Isso cria algo poderoso: uma interface.

Uma interface define quais operações estão disponíveis sem especificar como elas funcionam. É um contrato que diz "qualquer objeto que implemente esta interface deve fornecer estas funções".

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

typedef struct {
    LogFunc log;
} ILogger;

A struct ILogger não contém nada além de um ponteiro de função. Ela não possui dados próprios — ela puramente descreve comportamento. O prefixo "I" é uma convenção comum indicando que se trata de uma interface.

Qualquer código que aceite um ILogger não se importa para onde a mensagem de log vai. Ele poderia imprimir no console, escrever em um arquivo ou enviar dados por uma rede. O chamador apenas sabe que pode chamar log:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // Não sabemos COMO ele faz o log
}

Essa separação é a essência do polimorfismo. A função process funciona com qualquer implementação de logger — você pode trocar comportamentos sem alterar o código da função. Na próxima lição, você criará implementações concretas que cumprem este contrato de interface.

challenge icon

Desafio

Fácil

Vamos construir uma interface ICalculator — uma struct que contém apenas ponteiros de função, definindo quais operações qualquer calculadora deve suportar sem especificar como elas funcionam.

Você criará dois arquivos para organizar seu código:

  • calculator.h: Defina sua interface aqui. Crie um tipo de ponteiro de função chamado BinaryOp que recebe dois parâmetros int e retorna um int. Em seguida, defina uma struct ICalculator que contenha apenas dois ponteiros de função: operate (do tipo BinaryOp) e describe (um ponteiro de função que não recebe parâmetros e não retorna nada). Esta struct é puramente uma interface — ela não contém dados, apenas comportamento.
  • main.c: Inclua seu cabeçalho e implemente funções concretas que possam cumprir a interface:
    • add — retorna a soma de dois inteiros
    • multiply — retorna o produto de dois inteiros
    • describe_add — imprime Addition
    • describe_multiply — imprime Multiplication
    Em seguida, crie uma instância de ICalculator, conecte-a com base na entrada e use-a para realizar um cálculo.

Seu programa receberá três entradas: dois inteiros e um código de operação (1 para adição, 2 para multiplicação).

Com base no código de operação, conecte seu ICalculator com o par apropriado de funções. Em seguida, chame describe através da interface para imprimir o nome da operação, seguido pela chamada de operate para calcular e imprimir o resultado.

Exemplo de saída quando as entradas são 5, 3 e 1:

Addition
8

Exemplo de saída quando as entradas são 4, 7 e 2:

Multiplication
28

O ponto principal é que sua struct ICalculator define um contrato — qualquer código que a utilize sabe que pode chamar describe e operate, sem saber quais funções específicas estão conectadas. Lembre-se de usar guards de inclusão em seu arquivo de cabeçalho.

Folha de consulta

Uma interface é uma struct que contém apenas ponteiros de função, definindo quais operações estão disponíveis sem especificar como elas funcionam.

Definindo uma interface:

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

typedef struct {
    LogFunc log;
} ILogger;

O prefixo "I" é uma convenção comum indicando que se trata de uma interface. A struct não contém dados — ela descreve puramente o comportamento.

Usando uma interface:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // Nós não sabemos COMO ele registra o log
}

Esta separação permite o polimorfismo — a função trabalha com qualquer implementação da interface, permitindo que você troque comportamentos sem alterar o código da função.

Experimente você mesmo

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

// TODO: Implementar a função add
// Retorna a soma de dois inteiros


// TODO: Implementar a função multiply
// Retorna o produto de dois inteiros


// TODO: Implementar a função describe_add
// Imprime "Addition"


// TODO: Implementar a função describe_multiply
// Imprime "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: Criar uma instância de ICalculator
    
    
    // TODO: Com base no op_code (1 para add, 2 para multiply),
    // conecte a calculadora com as funções apropriadas
    
    
    // TODO: Chamar describe através da interface
    
    
    // TODO: Chamar operate através da interface e imprimir o resultado
    
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming