Home > Backend Development > C++ > Object-Oriented Programming in C? Implementing an Interface from Scratch

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

DDD
Release: 2025-01-21 10:07:08
Original
874 people have browsed it

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

Exploring the intricacies of computing often involves understanding not just how something works, but also why and how it could be built from scratch. This article delves into the concept of interfaces in object-oriented programming (OOP), using Java as a reference point, and then demonstrates a rudimentary C implementation.

A Simple Vehicle Pricing Example

Our example focuses on calculating vehicle prices: cars priced by speed, motorcycles by engine displacement (cc). We begin with a Java interface defining the core vehicle behavior:

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

This interface is then implemented by Car and Motorcycle classes:

<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>
Copy after login

A helper function prints the price:

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

The main method demonstrates usage:

<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>
Copy after login

Replicating this in C requires a different approach.

Implementing Interfaces in C: A Manual Approach

In C, we lack the built-in interface mechanism of Java. We'll simulate it using structs for data and functions for methods. The compiler doesn't handle interface resolution; we must do it manually.

Our "interface" skeleton:

<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>
Copy after login

The Car implementation:

<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>
Copy after login

The Motorcycle implementation (similar to 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>
Copy after login

The price printing function:

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

Crucially, we implement vehicle_free and vehicle_price using switch statements to handle different vehicle types:

<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>
Copy after login

The main function demonstrates usage:

<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>
Copy after login

A Practical Application: Abstract Syntax Trees (ASTs)

This manual interface approach is particularly useful in scenarios like parsing, where an Abstract Syntax Tree (AST) might benefit from a similar structure. Different node types in the AST can be represented as separate structs, all conforming to a common "interface" defined by a set of functions.

Conclusion

While C lacks built-in interfaces, simulating them with careful struct and function design provides a powerful mechanism for achieving similar OOP principles. This manual approach offers flexibility and control, particularly beneficial in complex projects like parsers and interpreters.

The above is the detailed content of Object-Oriented Programming in C? Implementing an Interface from Scratch. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template