Menu
Coddy logo textTech

Das Interface-Konzept

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

Bisher haben unsere Strukturen Daten und Verhalten miteinander vermischt: zum Beispiel einen Namen zusammen mit einem function pointer. Aber was wäre, wenn eine Struktur nur function pointer enthielte? Dadurch entsteht etwas Mächtiges: ein interface.

Ein interface definiert, welche Operationen verfügbar sind, ohne zu spezifizieren, wie sie funktionieren. Es ist ein Vertrag, der besagt: „Jedes Objekt, das dieses interface implementiert, muss diese functions bereitstellen.“

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

typedef struct {
    LogFunc log;
} ILogger;

Die ILogger-Struktur enthält nichts weiter als einen function pointer. Sie besitzt keine eigenen Daten. Sie beschreibt ausschließlich Verhalten. Das Präfix „I“ ist eine gängige Konvention und weist darauf hin, dass es sich um ein interface handelt.

Jeglicher Code, der ein ILogger akzeptiert, kümmert sich nicht darum, wohin die Protokollnachricht gesendet wird. Sie könnte auf der Konsole ausgegeben, in eine Datei geschrieben oder über ein Netzwerk gesendet werden. Die aufrufende Stelle weiß nur, dass sie log aufrufen kann:

void process(ILogger* logger, const char* msg) {
    logger->log(msg);  // Wir wissen nicht WIE es loggt
}

Diese Trennung ist das Wesen des Polymorphismus. Die process function funktioniert mit jeder logger-Implementierung. Du kannst Verhaltensweisen austauschen, ohne den Code der function zu ändern. In der nächsten Lektion wirst du konkrete Implementierungen Create, die diesen interface-Vertrag erfüllen.

challenge icon

Aufgabe

Einfach

Wir erstellen ein ICalculator-Interface: eine Struktur, die nur Funktionszeiger enthält und festlegt, welche Operationen jeder Taschenrechner unterstützen muss, ohne anzugeben, wie sie funktionieren.

Du wirst zwei Dateien erstellen, um deinen Code zu organisieren:

  • calculator.h: Define dein Interface hier. Create einen Funktionszeigertyp namens BinaryOp, der zwei int-parameters entgegennimmt und ein int zurückgibt. Define anschließend eine ICalculator-Struktur, die nur zwei Funktionszeiger enthält: operate (vom Typ BinaryOp) und describe (ein Funktionszeiger, der keine parameters entgegennimmt und nichts zurückgibt). Diese Struktur ist ein reines Interface. Sie enthält keine Daten, sondern nur Verhalten.
  • main.c: Binde deinen Header ein und implementiere konkrete Funktionen, die das Interface erfüllen können:
    • add: gibt die Summe zweier ganzer Zahlen zurück
    • multiply: gibt das product zweier ganzer Zahlen zurück
    • describe_add: gibt Addition aus
    • describe_multiply: gibt Multiplication aus
    Erstelle anschließend eine ICalculator-instance, verbinde sie anhand der Eingabe und verwende sie, um eine Berechnung durchzuführen.

Dein Programm erhält drei Eingaben: zwei integers und einen operationscode (1 für Addition, 2 für Multiplikation).

Based auf dem Operationscode verbindest du deinen ICalculator mit dem appropriate Funktionspaar. Rufe dann describe über das Interface auf, um den Namen der Operation auszugeben, und rufe anschließend operate auf, um das Ergebnis zu berechnen und auszugeben.

Beispielausgabe bei den Eingaben 5, 3 und 1:

Addition
8

Beispielausgabe bei den Eingaben 4, 7 und 2:

Multiplication
28

Die zentrale Erkenntnis ist, dass deine ICalculator-Struktur einen Vertrag definiert: Jeder Code, der sie verwendet, weiß, dass er describe und operate aufrufen kann, ohne zu wissen, welche konkreten functions verbunden sind. Denke daran, include guards in deiner Headerdatei zu verwenden.

Probier es selbst

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

// TODO: Implementiere die add-Funktion
// Gibt die Summe von zwei Ganzzahlen zurück


// TODO: Implementiere die multiply-Funktion
// Gibt das Produkt von zwei Ganzzahlen zurück


// TODO: Implementiere die describe_add-Funktion
// Gibt "Addition" aus


// TODO: Implementiere die describe_multiply-Funktion
// Prints "Multiplication"


int main() {
    int num1, num2, op_code;
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &op_code);
    
    // TODO: Erstelle eine ICalculator-Instanz
    
    
    // TODO: Basierend auf op_code (1 für add, 2 für multiply),
    // verdrahte den Calculator mit den entsprechenden Funktionen
    
    
    // TODO: Rufe describe über die Schnittstelle auf
    
    
    // TODO: Rufe operate über die Schnittstelle auf und gib das Ergebnis aus
    
    
    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

Übe selbstständig: Online-C-Compiler