Menu
Coddy logo textTech

Classes et méthodes abstraites

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

Parfois, vous souhaitez définir une classe qui sert de modèle mais qui ne devrait jamais être instanciée directement. Par exemple, une classe Shape générique est logique en tant que parent, mais à quoi ressemblerait une « forme » sans forme spécifique ? C'est là que les classes abstraites entrent en jeu.

Une classe abstraite est déclarée avec le mot-clé abstract et ne peut pas être instanciée. Elle peut contenir à la fois des méthodes régulières avec des implémentations et des méthodes abstraites qui n'ont pas de corps :

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Méthode abstraite - pas d'implémentation
    public abstract double getArea();
    
    // Méthode régulière - a une implémentation
    public String getColor() {
        return color;
    }
}

Les méthodes abstraites déclarent ce qu'une sous-classe doit faire, mais pas comment. Toute classe non abstraite étendant une classe abstraite doit fournir des implémentations pour toutes les méthodes abstraites :

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Vous pouvez toujours utiliser les classes abstraites comme types de référence, permettant le polymorphisme :

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // Appelle l'implémentation de Circle

Les classes abstraites sont idéales lorsque les sous-classes partagent du code commun mais doivent chacune implémenter certains comportements différemment. Elles imposent un contrat tout en permettant la réutilisation du code.

challenge icon

Défi

Facile

Construisons un système d’appareils qui démontre la puissance des classes abstraites. Vous allez créer une classe de base Appliance qui définit ce que chaque appareil doit faire, tout en laissant les types d’appareils spécifiques décider exactement comment ils le font.

Vous organiserez votre code sur quatre fichiers :

  • Appliance.java : Créez une classe abstraite qui sert de modèle pour tous les appareils. Chaque appareil possède un champ brand (String) et un champ wattage (int). Ajoutez un constructeur qui initialise les deux champs, des méthodes getter pour chacun d’eux, ainsi qu’une méthode ordinaire getInfo() qui renvoie : [brand] - [wattage]W. Définissez une méthode abstraite operate() que les sous-classes doivent implémenter : elle représente la manière dont chaque appareil exécute sa fonction principale.
  • WashingMachine.java : Créez une classe concrète qui étend Appliance. Les machines à laver possèdent un champ supplémentaire capacity (int) représentant la capacité de chargement en kg. Utilisez super pour gérer l’initialisation de la classe parente. Implémentez la méthode operate() afin d’afficher : [brand] washing machine is washing [capacity]kg of clothes
  • Microwave.java : Créez une autre classe concrète qui étend Appliance. Les micro-ondes possèdent un champ power (int) représentant le pourcentage du niveau de puissance. Implémentez operate() afin d’afficher : [brand] microwave is heating at [power]% power
  • Main.java : Regroupez tous les éléments en utilisant le polymorphisme. Vous recevrez cinq entrées : un nom de marque, la puissance en watts, la capacité de la machine à laver, un autre nom de marque et le niveau de puissance du micro-ondes. Créez une WashingMachine et un Microwave, puis stockez-les dans un tableau de références Appliance. Parcourez le tableau et, pour chaque appareil, affichez ses informations à l’aide de getInfo(), puis appelez operate().

Vous recevrez cinq entrées dans cet ordre : première marque (String), première puissance en watts (int), capacité en kg (int), deuxième marque (String) et niveau de puissance (int).

Votre sortie doit comporter quatre lignes : pour chaque appareil, vous verrez sa ligne d’informations suivie de son comportement. Remarquez comment la classe abstraite vous permet de traiter différents appareils de manière uniforme, tandis que chacun fonctionne selon sa propre façon unique !

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 brand1 = scanner.nextLine();
        int wattage1 = scanner.nextInt();
        int capacity = scanner.nextInt();
        scanner.nextLine(); // consommer le saut de ligne
        String brand2 = scanner.nextLine();
        int power = scanner.nextInt();
        
        // TODO: Créer un objet WashingMachine avec brand1, wattage1, et capacity
        
        // TODO: Créer un objet Microwave avec brand2, wattage1 (ou la puissance appropriée), et power
        
        // TODO: Créer un tableau de références Appliance et stocker les deux objets
        
        // TODO: Parcourir le tableau et pour chaque appliance :
        // - Afficher ses informations en utilisant getInfo()
        // - Appeler operate()
    }
}
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