Menu
Coddy logo textTech

Le concept d'interface

Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 40 sur 61.

Jusqu’à présent, nos structures ont regroupé les données et le comportement : un nom associé à un pointeur de fonction, par exemple. Mais que se passerait-il si une structure ne contenait que des pointeurs de fonction ? Cela crée quelque chose de puissant : une interface.

Une interface définit quelles opérations sont disponibles sans préciser comment elles fonctionnent. C’est un contrat qui stipule que « tout objet implémentant cette interface doit fournir ces fonctions ».

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

typedef struct {
    LogFunc log;
} ILogger;

La structure ILogger ne contient rien d’autre qu’un pointeur de fonction. Elle ne possède aucune donnée propre. Elle décrit uniquement un comportement. Le préfixe « I » est une convention courante indiquant qu’il s’agit d’une interface.

Tout code qui accepte un ILogger ne se soucie pas de l’endroit où le message de journalisation est envoyé. Il peut print dans la console, écrire dans un fichier ou envoyer des données sur un réseau. L’appelant sait simplement qu’il peut appeler log :

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // Nous ne savons pas COMMENT il journalise
}

Cette séparation est l’essence du polymorphisme. La fonction process fonctionne avec n’importe quelle implémentation de logger. Vous pouvez remplacer les comportements sans modifier le code de la fonction. Dans la prochaine leçon, vous créerez des implémentations concrètes qui respectent ce contrat d’interface.

challenge icon

Défi

Facile

Construisons une interface ICalculator : une structure qui contient uniquement des pointeurs de fonction et qui définit les opérations que toute calculatrice doit prendre en charge sans préciser leur fonctionnement.

Vous allez créer deux fichiers pour organiser votre code :

  • calculator.h : définissez votre interface ici. Créez un type de pointeur de fonction appelé BinaryOp qui accepte deux paramètres int et renvoie un int. Définissez ensuite une structure ICalculator qui contient uniquement deux pointeurs de fonction : operate (de type BinaryOp) et describe (un pointeur de fonction qui n'accepte aucun paramètre et ne renvoie rien). Cette structure est purement une interface. Elle ne contient aucune donnée, uniquement un comportement.
  • main.c : incluez votre fichier d'en-tête et implémentez des fonctions concrètes capables de satisfaire l'interface :
    • add : renvoie la somme de deux entiers
    • multiply : renvoie le produit de deux entiers
    • describe_add : affiche Addition
    • describe_multiply : affiche Multiplication
    Créez ensuite une instance de ICalculator, configurez-la en fonction de l'entrée, puis utilisez-la pour effectuer un calcul.

Votre programme recevra trois entrées : deux entiers et un code d'opération (1 pour l'addition, 2 pour la multiplication).

En fonction du code d'opération, configurez votre ICalculator avec la paire de fonctions appropriée. Appelez ensuite describe via l'interface pour afficher le nom de l'opération, puis appelez operate pour calculer et afficher le résultat.

Exemple de sortie lorsque les entrées sont 5, 3 et 1 :

Addition
8

Exemple de sortie lorsque les entrées sont 4, 7 et 2 :

Multiplication
28

L'idée essentielle est que votre structure ICalculator définit un contrat : tout code qui l'utilise sait qu'il peut appeler describe et operate, sans savoir quelles fonctions spécifiques sont connectées. N'oubliez pas d'utiliser des gardes d'inclusion dans votre fichier d'en-tête.

Essayez vous-même

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

// TODO: Implémenter la fonction add
// Retourne la somme de deux entiers


// TODO: Implémenter la fonction multiply
// Retourne le produit de deux entiers


// TODO: Implémenter la fonction describe_add
// Affiche "Addition"


// TODO: Implémenter la fonction describe_multiply
// Prints "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: Créer une instance de ICalculator
    
    
    // TODO: Selon op_code (1 pour add, 2 pour multiply),
    // connecter le calculateur aux fonctions appropriées
    
    
    // TODO: Appeler describe via l'interface
    
    
    // TODO: Appeler operate via l'interface et afficher le résultat
    
    
    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C en ligne