POO: classes abstraites vs interfaces (Java)
Tags: poo, java, interface, classe
Published: 2023-03-10 17:20:14

En programmation orientée objet (POO), les classes abstraites et les interfaces sont des concepts importants qui permettent de définir des modèles communs pour des classes spécifiques. Dans cet article, nous allons expliquer les caractéristiques de chaque concept et fournir des exemples simples pour mieux comprendre leur utilisation en Java.

### Classes abstraites en Java

Une **classe** abstraite est une classe qui **ne peut pas être instanciée directement**, mais qui sert de modèle pour des classes dérivées. Elle contient des **méthodes abstraites** (sans corps) qui doivent être implémentées dans les classes dérivées. Une classe abstraite peut également contenir des **méthodes non abstraites** qui ont une implémentation concrète.

Voici un exemple simple de classe abstraite pour une voiture :
```java
public abstract class Voiture {

  private String marque;
  private String modele;
  
  public Voiture(String marque, String modele) {
    this.marque = marque;
    this.modele = modele;
  }
  
  public String getMarque() {
    return marque;
  }
  
  public String getModele() {
    return modele;
  }
  
  public abstract void demarrer();
  public abstract void arreter();

}
```
Dans cet exemple, la classe **Voiture** est **abstraite** car elle contient des méthodes abstraites **demarrer()** et **arreter()**. Ces méthodes seront obligatoirement implémentées dans des classes dérivées qui étendent Voiture. Sinon, la sous-classe doit elle-même être déclarée abstraite. 

La classe Voiture contient également des méthodes non abstraites getMarque() et getModele() qui ont une implémentation concrète.

### Interfaces en Java

Une **interface** en Java est un ensemble de **méthodes abstraites** qui définissent le **comportement** d'un objet. Les interfaces peuvent être implémentées par des classes pour définir un comportement commun pour ces classes.

Voici un exemple simple d'interface pour une voiture :
```java
public interface Voiture {

  public void demarrer();
  public void arreter();

}
```
Dans cet exemple, l'interface **Voiture** définit deux méthodes abstraites **demarrer()** et **arreter()**. Les classes qui implémentent cette interface doivent fournir une implémentation pour ces méthodes.

### Différences entre les classes abstraites et les interfaces

Voici les principales différences entre les classes abstraites et les interfaces :

- Une classe abstraite peut contenir des méthodes non abstraites avec une implémentation concrète, tandis qu'une interface ne peut contenir que des méthodes abstraites sans implémentation.
- Une **classe abstraite** peut implémenter **plusieurs interfaces**, mais elle ne peut **hériter** que d'**une seule classe** (abstraite ou non), car l'héritage multiple peut conduire à des conflits de noms et de comportements et peut rendre le code plus complexe et difficile à maintenir.
- Les **classes abstraites** sont souvent utilisées pour définir des **classes de base génériques**, tandis que les **interfaces** sont utilisées pour définir des **comportements communs** pour des classes qui n'ont pas nécessairement de relation d'héritage.

### Quand utiliser une classe abstraite ou une interface

- Utilisez une **classe abstraite** si vous avez besoin de fournir une **implémentation de base** pour une classe dérivée et que cette implémentation est utilisée par plusieurs classes dérivées. Les classes dérivées peuvent ajouter des méthodes et des fonctionnalités supplémentaires en plus de l'implémentation de base fournie par la classe abstraite.
- Utilisez une **interface** si vous voulez définir un **comportement commun** pour des classes qui n'ont pas de relation d'héritage directe. Les classes qui implémentent l'interface fournissent leur propre implémentation pour les méthodes abstraites définies dans l'interface.

### Conclusion

En somme, les classes abstraites et les interfaces sont deux outils clés de la programmation orientée objet en Java. Les classes abstraites permettent de fournir une implémentation de base pour les classes dérivées, tandis que les interfaces définissent un comportement commun pour les classes qui n'ont pas de relation d'héritage directe. L'utilisation de ces concepts peut aider à définir des modèles communs pour les classes spécifiques, à améliorer la maintenabilité et la réutilisabilité du code, et à renforcer la conception orientée objet d'un programme Java.