Menu
Coddy logo textTech

Interfaces implementieren

Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 41 von 61.

Nachdem Sie nun verstehen, was ein Interface ist — ein Struct, das nur Funktionszeiger enthält — ist es an der Zeit, konkrete Implementierungen zu erstellen, die diesen Vertrag erfüllen.

Erinnern Sie sich an unser ILogger-Interface aus der vorherigen Lektion:

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

typedef struct {
    LogFunc log;
} ILogger;

Um dieses Interface zu implementieren, schreiben wir tatsächliche Funktionen, die der LogFunc-Signatur entsprechen, und erstellen dann ILogger-Instanzen, denen diese Funktionen zugewiesen sind:

void console_log(const char* message) {
    printf("[CONSOLE] %s\n", message);
}

void file_log(const char* message) {
    printf("[FILE] %s\n", message);  // Dateiausgabe wird simuliert
}

ILogger create_console_logger() {
    ILogger logger = { console_log };
    return logger;
}

ILogger create_file_logger() {
    ILogger logger = { file_log };
    return logger;
}

Jede „Constructor“-Funktion gibt ein ILogger mit einer anderen eingebundenen Funktion zurück. Code, der diese Logger verwendet, muss nicht wissen, welche Implementierung er erhalten hat:

void do_work(ILogger* logger) {
    logger->log("Starting work...");
    logger->log("Work complete!");
}

int main() {
    ILogger console = create_console_logger();
    ILogger file = create_file_logger();
    
    do_work(&console);  // Verwendet console_log
    do_work(&file);     // Verwendet file_log
    return 0;
}

Die Funktion do_work ist vollständig von der Logging-Implementierung entkoppelt. Sie können Logger frei austauschen, ohne die Kernlogik zu ändern – das ist die Stärke der Programmierung gegen ein Interface.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein INotifier-System bauen, das demonstriert, wie verschiedene Implementierungen denselben Interface-Vertrag erfüllen können. Sie werden konkrete Notifier erstellen — einen EmailNotifier und einen SMSNotifier —, die beide einem gemeinsamen Interface entsprechen, aber unterschiedliche Ausgaben erzeugen.

Sie werden Ihren Code über drei Dateien organisieren:

  • notifier.h: Definieren Sie hier das Interface. Erstellen Sie einen Funktionszeigertyp namens NotifyFunc, der eine const char* Nachricht entgegennimmt und nichts zurückgibt. Definieren Sie dann ein INotifier-Struct, das nur einen notify-Funktionszeiger dieses Typs enthält. Deklarieren Sie außerdem zwei Konstruktorfunktionen: create_email_notifier und create_sms_notifier, die jeweils einen INotifier als Wert zurückgeben.
  • notifier.c: Implementieren Sie hier die konkreten Benachrichtigungsfunktionen und Konstruktoren. Erstellen Sie:
    • email_notify — gibt die Nachricht im Format [EMAIL] message aus
    • sms_notify — gibt die Nachricht im Format [SMS] message aus
    • create_email_notifier — gibt einen INotifier zurück, der mit email_notify verknüpft ist
    • create_sms_notifier — gibt einen INotifier zurück, der mit sms_notify verknüpft ist
  • main.c: Führen Sie hier alles zusammen. Lesen Sie einen Benachrichtigungstyp und eine Nachricht ein, erstellen Sie den entsprechenden Notifier mithilfe der Konstruktorfunktionen und senden Sie die Benachrichtigung über das Interface.

Ihr Programm erhält zwei Eingaben: einen Benachrichtigungstyp (1 für E-Mail, 2 für SMS) und eine zu sendende Nachricht.

Verwenden Sie die Konstruktorfunktionen, um den entsprechenden Notifier zu erstellen, und rufen Sie dann notify über das Interface auf, um die Nachricht anzuzeigen.

Beispielausgabe, wenn der Typ 1 und die Nachricht Meeting at 3pm ist:

[EMAIL] Meeting at 3pm

Beispielausgabe, wenn der Typ 2 und die Nachricht Your code shipped ist:

[SMS] Your code shipped

Die Stärke dieses Musters liegt darin, dass main.c nicht wissen muss, wie jeder Notifier intern funktioniert — es ruft einfach die notify-Funktion des Interfaces auf, und die korrekte Implementierung wird ausgeführt. Denken Sie daran, Include-Guards in Ihrer Header-Datei zu verwenden.

Probier es selbst

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

int main() {
    int type;
    char message[256];
    
    // Benachrichtigungstyp einlesen (1 für E-Mail, 2 für SMS)
    scanf("%d", &type);
    getchar(); // Zeilenumbruch konsumieren
    
    // Nachricht einlesen
    fgets(message, sizeof(message), stdin);
    // Abschließenden Zeilenumbruch entfernen, falls vorhanden
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: Den passenden Notifier basierend auf dem Typ erstellen
    // Verwende create_email_notifier() für Typ 1
    // Verwende create_sms_notifier() für Typ 2
    
    // TODO: Die notify-Funktion über das Interface aufrufen
    // notifier.notify(message);
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming