Heim >Backend-Entwicklung >C++ >Objektorientierte Programmierung in C? Implementierung einer Schnittstelle von Grund auf

Objektorientierte Programmierung in C? Implementierung einer Schnittstelle von Grund auf

DDD
DDDOriginal
2025-01-21 10:07:08926Durchsuche

Object-Oriented Programming in C? Implementing an Interface from Scratch

Um die Feinheiten der Informatik zu erforschen, geht es oft darum, nicht nur zu verstehen, wie etwas funktioniert, sondern auch warum und wie es von Grund auf neu erstellt werden könnte. Dieser Artikel befasst sich unter Verwendung von Java als Bezugspunkt mit dem Konzept von Schnittstellen in der objektorientierten Programmierung (OOP) und demonstriert anschließend eine rudimentäre C-Implementierung.

Ein einfaches Beispiel für die Fahrzeugpreisgestaltung

Unser Beispiel konzentriert sich auf die Berechnung der Fahrzeugpreise: Preise für Autos nach Geschwindigkeit, Motorräder nach Hubraum (cm³). Wir beginnen mit einer Java-Schnittstelle, die das Kernverhalten des Fahrzeugs definiert:

<code class="language-java">public interface Vehicle {
    Integer price();
}</code>

Diese Schnittstelle wird dann durch die Klassen Car und Motorcycle implementiert:

<code class="language-java">public class Car implements Vehicle {
    private final Integer speed;
    public Car(Integer speed) { this.speed = speed; }
    @Override public Integer price() { return speed * 60; }
}

public class Motorcycle implements Vehicle {
    private final Integer cc;
    public Motorcycle(Integer cc) { this.cc = cc; }
    @Override public Integer price() { return cc * 10; }
}</code>

Eine Hilfsfunktion druckt den Preis:

<code class="language-java">public static void printVehiclePrice(Vehicle vehicle) {
    System.out.println("$" + vehicle.price() + ".00");
}</code>

Die Hauptmethode demonstriert die Verwendung:

<code class="language-java">public static void main(String[] args) {
    Car car = new Car(120);
    Motorcycle motorcycle = new Motorcycle(1000);
    printVehiclePrice(car);  // Output: 00.00
    printVehiclePrice(motorcycle); // Output: 000.00
}</code>

Um dies in C zu reproduzieren, ist ein anderer Ansatz erforderlich.

Schnittstellen in C implementieren: Ein manueller Ansatz

In C fehlt uns der integrierte Schnittstellenmechanismus von Java. Wir simulieren es mithilfe von Strukturen für Daten und Funktionen für Methoden. Der Compiler kümmert sich nicht um die Schnittstellenauflösung. wir müssen es manuell tun.

Unser „Schnittstellen“-Skelett:

<code class="language-c">#include <stdio.h>
#include <stdlib.h>

typedef enum { VEHICLE_CAR, VEHICLE_MOTORCYCLE } VehicleType;

typedef struct {
    VehicleType type;
} Vehicle;

void vehicle_free(Vehicle *vehicle);
int vehicle_price(Vehicle *vehicle);</code>

Die Car Implementierung:

<code class="language-c">typedef struct {
    VehicleType type;
    int speed;
} Car;

Car *car_init(int speed) {
    Car *car = malloc(sizeof(Car));
    car->type = VEHICLE_CAR;
    car->speed = speed;
    return car;
}

void car_free(Car *car) { free(car); }
int car_price(Car *car) { return car->speed * 60; }</code>

Die Motorcycle Implementierung (ähnlich zu Car):

<code class="language-c">typedef struct {
    VehicleType type;
    int cc;
} Motorcycle;

Motorcycle *motorcycle_init(int cc) {
    Motorcycle *motorcycle = malloc(sizeof(Motorcycle));
    motorcycle->type = VEHICLE_MOTORCYCLE;
    motorcycle->cc = cc;
    return motorcycle;
}

void motorcycle_free(Motorcycle *motorcycle) { free(motorcycle); }
int motorcycle_price(Motorcycle *motorcycle) { return motorcycle->cc * 10; }</code>

Die Preisdruckfunktion:

<code class="language-c">void print_vehicle_price(Vehicle *vehicle) {
    printf("$%d.00\n", vehicle_price(vehicle));
}</code>

Entscheidend ist, dass wir vehicle_free und vehicle_price mithilfe von switch-Anweisungen implementieren, um verschiedene Fahrzeugtypen zu handhaben:

<code class="language-c">void vehicle_free(Vehicle *vehicle) {
    switch (vehicle->type) {
        case VEHICLE_CAR: car_free((Car *)vehicle); break;
        case VEHICLE_MOTORCYCLE: motorcycle_free((Motorcycle *)vehicle); break;
    }
}

int vehicle_price(Vehicle *vehicle) {
    switch (vehicle->type) {
        case VEHICLE_CAR: return car_price((Car *)vehicle);
        case VEHICLE_MOTORCYCLE: return motorcycle_price((Motorcycle *)vehicle);
    }
}</code>

Die Hauptfunktion demonstriert die Verwendung:

<code class="language-c">int main(void) {
    Car *car = car_init(120);
    Motorcycle *motorcycle = motorcycle_init(1000);
    print_vehicle_price((Vehicle *)car);  // Output: 00.00
    print_vehicle_price((Vehicle *)motorcycle); // Output: 000.00
    vehicle_free((Vehicle *)car);
    vehicle_free((Vehicle *)motorcycle);
    return 0;
}</code>

Eine praktische Anwendung: Abstrakte Syntaxbäume (ASTs)

Dieser manuelle Schnittstellenansatz ist besonders nützlich in Szenarien wie dem Parsen, in denen ein Abstract Syntax Tree (AST) von einer ähnlichen Struktur profitieren könnte. Verschiedene Knotentypen im AST können als separate Strukturen dargestellt werden, die alle einer gemeinsamen „Schnittstelle“ entsprechen, die durch eine Reihe von Funktionen definiert ist.

Fazit

Während es in C an integrierten Schnittstellen mangelt, bietet deren Simulation mit sorgfältigem Struktur- und Funktionsdesign einen leistungsstarken Mechanismus zum Erreichen ähnlicher OOP-Prinzipien. Dieser manuelle Ansatz bietet Flexibilität und Kontrolle, was besonders bei komplexen Projekten wie Parsern und Interpretern von Vorteil ist.

Das obige ist der detaillierte Inhalt vonObjektorientierte Programmierung in C? Implementierung einer Schnittstelle von Grund auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn