Explorer les subtilités de l'informatique implique souvent de comprendre non seulement comment quelque chose fonctionne, mais aussi pourquoi et comment cela pourrait être construit à partir de zéro. Cet article approfondit le concept d'interfaces dans la programmation orientée objet (POO), en utilisant Java comme point de référence, puis démontre une implémentation rudimentaire en C.
Notre exemple se concentre sur le calcul des prix des véhicules : les voitures sont tarifées en fonction de la vitesse, les motos en fonction de la cylindrée du moteur (cc). Nous commençons par une interface Java définissant le comportement principal du véhicule :
<code class="language-java">public interface Vehicle { Integer price(); }</code>
Cette interface est ensuite implémentée par les classes Car
et Motorcycle
:
<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>
Une fonction d'assistance imprime le prix :
<code class="language-java">public static void printVehiclePrice(Vehicle vehicle) { System.out.println("$" + vehicle.price() + ".00"); }</code>
La méthode principale démontre l'utilisation :
<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>
Répliquer cela en C nécessite une approche différente.
En C, il nous manque le mécanisme d'interface intégré de Java. Nous allons le simuler en utilisant des structures pour les données et des fonctions pour les méthodes. Le compilateur ne gère pas la résolution d'interface ; nous devons le faire manuellement.
Notre squelette "interface":
<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>
La Car
mise en œuvre :
<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>
L'implémentation Motorcycle
(similaire à 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>
La fonction d'impression des prix :
<code class="language-c">void print_vehicle_price(Vehicle *vehicle) { printf("$%d.00\n", vehicle_price(vehicle)); }</code>
Il est essentiel que nous implémentions vehicle_free
et vehicle_price
en utilisant les instructions switch
pour gérer différents types de véhicules :
<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>
La fonction principale démontre l'utilisation :
<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>
Cette approche d'interface manuelle est particulièrement utile dans des scénarios tels que l'analyse syntaxique, où un arbre de syntaxe abstraite (AST) pourrait bénéficier d'une structure similaire. Différents types de nœuds dans l'AST peuvent être représentés sous forme de structures distinctes, toutes conformes à une « interface » commune définie par un ensemble de fonctions.
Bien que C manque d'interfaces intégrées, les simuler avec une conception minutieuse des structures et des fonctions fournit un mécanisme puissant pour atteindre des principes de POO similaires. Cette approche manuelle offre flexibilité et contrôle, particulièrement bénéfiques dans les projets complexes tels que les analyseurs et les interprètes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!