Abstraction
L'abstraction est l'un des quatre piliers fondamentaux de la programmation orientée objet, avec l'encapsulation, l'héritage et le polymorphisme.
Elle consiste à se concentrer sur les caractéristiques essentielles d'un objet, tout en masquant les détails de son implémentation.
Autrement dit, l'abstraction répond à la question :
- Que fait l'objet ?
- et non
- Comment le fait-il ?
Elle permet ainsi de fournir une vue simplifiée et conceptuelle d'un système complexe.
Pourquoi l'abstraction est-elle indispensable ?
L'abstraction répond à des besoins fondamentaux en ingénierie logicielle :
Réduction de la complexité
Les détails techniques sont cachés derrière des concepts simples et compréhensibles.
Séparation des responsabilités
L'utilisateur d'un objet n'a pas besoin de connaître son fonctionnement interne.
Indépendance de l'implémentation
Une implémentation peut être modifiée sans impacter le code client.
Facilitation du travail en équipe
Les contrats sont clairement définis, même si les implémentations sont développées séparément.
Abstraction vs encapsulation
Bien que proches, ces deux notions sont distinctes :
| Abstraction | Encapsulation |
|---|---|
| Cache la complexité | Cache les données |
| Définit un contrat | Contrôle l'accès |
| « Quoi » | « Comment » |
| Interfaces / classes abstraites | Modificateurs d'accès |
L'encapsulation protège, l'abstraction simplifie.
Les outils de l'abstraction en POO
L'abstraction est mise en ouvre principalement à l'aide de :
- Classes abstraites
- Interfaces
Les classes abstraites
Définition
Une classe abstraite est une classe :
- qui ne peut pas être instanciée
- qui peut contenir :
- des méthodes abstraites (sans implémentation)
- des méthodes concrètes
- des attributs
Elle sert de base commune à des classes spécialisées.
Exemple simple
Voici un exemple en Java :
Implémentation dans une classe concrète
Voici un exemple en Java :
Utilisation
Voici un exemple en Java :
- Animal animal = new Chien("Rex");
- animal.crier();
- animal.dormir();
Le code utilise l'abstraction (Animal), pas l'implémentation (Chien).
Les méthodes abstraites
Rôle
Une méthode abstraite :
- ne contient pas de code
- impose un comportement aux classes filles
- définit un contrat obligatoire
Voici un exemple en Java :
Obligation d'implémentation
Toute classe concrète héritant d'une classe abstraite doit implémenter toutes les méthodes abstraites, sous peine d'être elle-même abstraite.
Les interfaces
Définition
Une interface définit un contrat pur :
- uniquement des signatures de méthodes (et constantes)
- aucune logique métier (sauf méthodes par défaut selon le langage)
- aucune instanciation possible
Exemple d'interface
Implémentation
Utilisation
Voici un exemple en Java :
Volant v = new Oiseau();
v.voler();
Classe abstraite vs interface
| Classe abstraite | Interface |
|---|---|
| Peut contenir des attributs | Pas d'état |
| Méthodes concrètes possibles | Contrat pur |
| Héritage simple | Héritage multiple |
| Relation IS-A | Capacité / rôle |
Abstraction et polymorphisme
L'abstraction est le socle du polymorphisme :
Le comportement varie selon l'implémentation, pas selon le type de référence.
Abstraction et conception orientée objet
Programmation orientée interfaces
Principe clef :
Programmer contre des abstractions, pas des implémentations
Exemple en Java :
- void faireVoler(Volant v) {
- v.voler();
- }
Inversion des dépendances (SOLID)
L'abstraction est au cour du principe D de SOLID :
Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau, mais d'abstractions.
Mauvaises utilisations de l'abstraction
- Abstraire trop tôt
- Créer des abstractions inutiles
- Multiplier les interfaces sans besoin réel
- Mélanger abstraction et implémentation
Une abstraction doit être justifiée par un besoin concret.
Bonnes pratiques
- Identifier les comportements communs
- Définir des contrats clairs et stables
- Utiliser des interfaces pour les rôles
- Utiliser des classes abstraites pour le partage de code
- Documenter les abstractions
Exemple complet et réaliste
Voici un exemple de l'abstraction d'un système de paiement en Java :
- interface MoyenPaiement {
- void payer(double montant);
- }
-
- class CarteBancaire implements MoyenPaiement {
- public void payer(double montant) {
- System.out.println("Paiement par carte : " + montant);
- }
- }
-
- class Paypal implements MoyenPaiement {
- public void payer(double montant) {
- System.out.println("Paiement via Paypal : " + montant);
- }
- }
Utilisation :
- void effectuerPaiement(MoyenPaiement moyen) {
- moyen.payer(100);
- }
Abstraction et UML
- Classe abstraite : nom en italique
- Méthode abstraite : italique
- Interface : stéréotype <<interface>>
Conclusion
L'abstraction est un outil fondamental pour maîtriser la complexité. Elle permet de concevoir des systèmes flexibles, évolutifs et robustes en séparant clairement ce qui est fait de la manière dont cela est fait.