Menu
Coddy logo textTech

Classes Abstraites vs Interfaces

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 38 sur 87.

Maintenant que vous comprenez à la fois les classes abstraites et les interfaces, une question courante se pose : quand devriez-vous utiliser l’une plutôt que l’autre ? Le choix dépend de ce que vous essayez de modéliser.

Utilisez une classe abstraite lorsque les classes partagent une base commune avec un état ou un comportement partagé. Les classes abstraites peuvent avoir des variables d’instance, des constructeurs et un mélange de méthodes abstraites et concrètes :

public abstract class Animal {
    protected String name;  // état partagé
    
    public Animal(String name) {
        this.name = name;
    }
    
    public void sleep() {  // comportement partagé
        System.out.println(name + " is sleeping");
    }
    
    public abstract void makeSound();  // doit être implémenté
}

Utilisez une interface lorsque vous souhaitez définir une capacité que des classes sans lien peuvent partager. Les interfaces se concentrent sur ce qu’un objet peut faire, et non sur ce qu’il est :

public interface Flyable {
    void fly();
}

// Des classes non liées peuvent partager cette capacité
class Bird extends Animal implements Flyable { ... }
class Airplane implements Flyable { ... }
class Drone implements Flyable { ... }

Voici une comparaison rapide :

FonctionnalitéClasse abstraiteInterface
Variables d’instanceOuiConstantes uniquement
ConstructeursOuiNon
Héritage multipleNon (un seul extends)Oui (plusieurs implements)
Modificateurs d’accèsN’importe lequelPublic uniquement (pour les méthodes abstraites)

Une règle pratique : si vous vous retrouvez à créer une classe abstraite avec uniquement des méthodes abstraites et aucun état, une interface est probablement le meilleur choix.

challenge icon

Défi

Facile

Construisons un système de véhicules qui montre quand utiliser des classes abstraites plutôt que des interfaces. Vous modéliserez des véhicules qui partagent un état et un comportement communs grâce à une classe abstraite, tout en ajoutant des fonctionnalités facultatives grâce à des interfaces.

Vous organiserez votre code sur cinq fichiers :

  • Vehicle.java : créez une classe abstraite qui sert de base à tous les véhicules. Chaque véhicule possède un champ brand (String) et un champ year (int). Ajoutez un constructeur pour initialiser les deux champs, des méthodes d'accès pour chacun d'eux, ainsi qu'une méthode abstraite startEngine() qui renvoie une String. Ajoutez également une méthode concrète getInfo() qui renvoie : [brand] ([year]). C'est un cas d'utilisation idéal pour une classe abstraite : les véhicules partagent un état (brand, year) et une partie de leur comportement (getInfo), mais chacun démarre son moteur différemment.
  • Convertible.java : définissez une interface pour les véhicules dont le toit peut être escamoté. Cette capacité n'est pas liée à ce qu'est un véhicule : c'est quelque chose que certains véhicules peuvent faire. Déclarez deux méthodes : openRoof() et closeRoof(), qui renvoient toutes deux une String.
  • Car.java : créez une classe qui étend Vehicle et implémente Convertible. Une Car possède un champ supplémentaire numDoors (int). Utilisez super pour initialiser les champs hérités. Implémentez startEngine() pour renvoyer : [brand] car engine started. Implémentez openRoof() pour renvoyer : [brand] roof opening et closeRoof() pour renvoyer : [brand] roof closing.
  • Motorcycle.java : créez une classe qui étend Vehicle, mais n'implémente PAS Convertible : les motos n'ont pas de toit ! Une Motorcycle possède un champ hasSidecar (boolean). Implémentez startEngine() pour renvoyer : [brand] motorcycle engine roaring.
  • Main.java : rassemblez tous les éléments pour mettre en évidence la différence entre les classes abstraites et les interfaces. Vous recevrez quatre entrées : la marque d'une voiture, l'année d'une voiture, la marque d'une moto et l'année d'une moto.

    Créez une Car (avec 4 portes) et une Motorcycle (sans side-car). Commencez par démontrer le comportement partagé de la classe abstraite en affichant getInfo() pour les deux véhicules. Ils héritent tous deux de cette méthode de Vehicle. Affichez ensuite le résultat de startEngine() pour chacun : remarquez comment chaque type de véhicule l'implémente différemment.

    Enfin, démontrez la capacité fournie par l'interface : puisque seule la Car implémente Convertible, appelez et affichez openRoof(), puis closeRoof(), uniquement sur la voiture.

Vous recevrez quatre entrées : la marque de la voiture (String), l'année de la voiture (int), la marque de la moto (String) et l'année de la moto (int).

Votre sortie doit afficher six lignes au total. Remarquez que les deux véhicules partagent l'état de la classe abstraite et la méthode getInfo(), mais que seule la Car possède la capacité de toit escamotable. Cela illustre quand utiliser chacune de ces approches !

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire les entrées
        String carBrand = scanner.nextLine();
        int carYear = scanner.nextInt();
        scanner.nextLine(); // consommer la nouvelle ligne
        String motorcycleBrand = scanner.nextLine();
        int motorcycleYear = scanner.nextInt();
        
        // TODO: Créer une Car avec 4 portes
        
        // TODO: Créer une Motorcycle sans side-car (false)
        
        // TODO: Afficher getInfo() pour les deux véhicules (démontre le comportement partagé de la classe abstraite)
        
        // TODO: Afficher startEngine() pour les deux véhicules (démontre des implémentations différentes)
        
        // TODO: Afficher openRoof() et closeRoof() pour la voiture uniquement (démontre la capacité de l'interface)
    }
}
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 Java en ligne