Menu
CoddyTech

Interface vs Classe Abstraite

Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy. Leçon 26 sur 70.

Les interfaces et les classes abstraites permettent toutes deux de définir des contrats que les autres classes doivent respecter, mais elles répondent à des objectifs différents et ont des fonctionnalités distinctes.

Une interface définit ce qu'une classe doit faire, sans aucune implémentation. C'est un contrat pur :

public interface IFlyable
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Flapping wings");
    }
}

Une classe abstraite peut fournir à la fois un contrat et une implémentation partagée. C'est un plan partiel :

public abstract class Vehicle
{
    public string Brand { get; set; }
    
    public void StartEngine()
    {
        Console.WriteLine("Engine started");
    }
    
    public abstract void Drive();  // Doit être implémenté
}

public class Car : Vehicle
{
    public override void Drive()
    {
        Console.WriteLine("Driving on roads");
    }
}

Les principales différences tiennent aux règles d’héritage et à l’objectif.

Une classe peut implémenter plusieurs interfaces, mais n’hériter que d’une seule classe abstraite.

Une classe peut également hériter d’une classe abstraite et implémenter des interfaces en même temps : après les deux-points, la classe de base vient en premier, puis les interfaces, séparées par des virgules :

public class Airplane : Vehicle, IFlyable
{
    public override void Drive()
    {
        Console.WriteLine("Taxiing to the runway");
    }

    public void Fly()
    {
        Console.WriteLine("Flying above the clouds");
    }
}

Utilise une interface lorsque des classes sans lien doivent partager un comportement (comme IFlyable pour les oiseaux et les avions). Utilise une classe abstraite lorsque des classes apparentées partagent du code et un état communs (comme les véhicules qui partagent un mécanisme de démarrage du moteur).

Les classes abstraites peuvent avoir des constructeurs, des champs et des modificateurs d’accès sur leurs membres. Les interfaces ne le pouvaient traditionnellement pas, bien que le C# moderne autorise les implémentations par défaut.

En cas de doute, privilégie les interfaces pour plus de flexibilité : tu pourras toujours ajouter une classe abstraite plus tard si une implémentation commune devient nécessaire.

challenge icon

Défi

Facile

Construisons un système de lecteur multimédia qui montre quand utiliser des interfaces plutôt que des classes abstraites. Tu vas créer une conception où des appareils sans lien entre eux partagent le comportement de lecture grâce à une interface, tandis que des types de médias apparentés partagent une implémentation commune grâce à une classe abstraite.

Tu vas organiser ton code sur quatre fichiers :

  • IPlayable.cs : définis une interface appelée IPlayable dans l’espace de noms Media. Cette interface représente le contrat pour tout ce qui peut lire des médias — qu’il s’agisse d’un téléphone, d’une télévision ou d’un lecteur de musique dédié. Elle doit déclarer une seule méthode Play() qui renvoie une chaîne de caractères.
  • MediaFile.cs : définis une classe abstraite appelée MediaFile dans l’espace de noms Media. Elle représente la base commune de tous les fichiers multimédias. Elle doit avoir une propriété Title (string) et une propriété Duration (int, représentant le nombre de secondes). Inclus un constructeur qui définit ces deux valeurs. Ajoute une méthode concrète appelée GetInfo() qui renvoie "{Title} ({Duration}s)". Déclare également une méthode abstraite GetType() qui renvoie une chaîne de caractères — chaque type de média définira de quel genre de fichier il s’agit.
  • AudioFile.cs : définis une classe AudioFile dans l’espace de noms Media qui hérite de MediaFile et implémente IPlayable. Ajoute une propriété Artist (string). Le constructeur doit accepter le titre, la durée et l’artiste. Redéfinis GetType() pour qu’elle renvoie "Audio". Implémente Play() pour qu’elle renvoie "Playing audio: {Title} by {Artist}".
  • Program.cs : dans ton fichier principal, crée un AudioFile à partir des valeurs saisies. Montre les deux aspects de la classe : appelle GetInfo() et GetType() (héritées de la classe abstraite), puis appelle Play() (de l’interface). Stocke le fichier audio dans une variable IPlayable et appelle à nouveau Play() pour montrer le polymorphisme d’interface.

Tu recevras trois entrées :

  • Titre de la chanson
  • Durée en secondes
  • Nom de l’artiste

Affiche la sortie dans ce format :

Info: {GetInfo() result}
Type: {GetType() result}
Direct: {Play() result}
Via Interface: {Play() result from IPlayable variable}

Par exemple, si les entrées sont Bohemian Rhapsody, 354 et Queen, la sortie doit être :

Info: Bohemian Rhapsody (354s)
Type: Audio
Direct: Playing audio: Bohemian Rhapsody by Queen
Via Interface: Playing audio: Bohemian Rhapsody by Queen

Remarque comme AudioFile tire parti des deux approches : elle hérite de l’implémentation partagée (GetInfo()) de la classe abstraite tout en respectant le contrat IPlayable. La classe abstraite permet de réutiliser le code pour des types de médias apparentés, tandis que l’interface permet à n’importe quelle classe sans lien d’être « jouable » sans partager une hiérarchie d’héritage.

Essayez vous-même

using System;
using Media;

class Program
{
    public static void Main(string[] args)
    {
        // Lire les valeurs d'entrée
        string title = Console.ReadLine();
        int duration = Convert.ToInt32(Console.ReadLine());
        string artist = Console.ReadLine();
        
        // TODO: Créer un AudioFile à partir des valeurs d'entrée
        
        // TODO: Afficher Info: suivi du résultat de GetInfo()
        
        // TODO: Afficher Type: suivi du résultat de GetType()
        
        // TODO: Afficher Direct: suivi du résultat de Play()
        
        // TODO: Stocker le fichier audio dans une variable IPlayable
        
        // TODO: Afficher Via Interface: suivi du résultat de Play() obtenu à partir de la variable IPlayable
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C# en ligne