ProgrammationDéveloppeur Java

Décrivez les principales différences entre les classes abstraites et les interfaces en Java, ainsi que les scénarios dans lesquels il convient d'utiliser chacune d'elles.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Les classes abstraites peuvent contenir à la fois des méthodes abstraites et des méthodes concrètes (avec une implémentation), ainsi que des états (champs de données). Une classe ne peut hériter que d'une seule classe abstraite. Les classes abstraites sont utilisées lorsque l'on doit regrouper une certaine logique et état pour une hiérarchie d'héritiers.

Les interfaces définissent uniquement les signatures des méthodes (jusqu'à Java 8), depuis Java 8, elles peuvent contenir des méthodes avec des implémentations par défaut et des méthodes statiques, mais n'ont pas d'état. Une classe peut implémenter de nombreuses interfaces. Utilisez des interfaces pour définir un ensemble de comportements indépendants de la hiérarchie d'héritage.

Exemple :

abstract class Animal { String name; public Animal(String name) { this.name = name; } abstract void makeSound(); } interface Movable { void move(); } class Dog extends Animal implements Movable { public Dog(String name) { super(name); } void makeSound() { System.out.println("Woof!"); } public void move() { System.out.println("Runs"); } }

Question piège

Quelle est la différence entre une classe abstraite avec uniquement des méthodes abstraites et une interface avant Java 8 ? Peut-on les utiliser de manière interchangeable ?

Réponse : Non, pas toujours. Une interface ne peut pas contenir d'état (champs d'instance) et prend en charge l'implémentation multiple, alors que l'héritage d'une classe abstraite est unique. De plus, les signatures des méthodes d'une interface sont toujours publiques.


Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire

Un projet nécessitait la réalisation de plusieurs interfaces se comportant de manière similaire, mais appartenant à différentes hiérarchies d'objets. Le développeur a choisi d'utiliser une classe abstraite, ce qui a rendu impossible l'utilisation de l'héritage multiple. Cela a conduit à un refactoring significatif et à une duplication de code.


Histoire

Dans un grand projet API REST, une interface avec des champs (constantes) a été créée, en supposant qu'il s'agirait de valeurs modifiables, comme dans une classe ordinaire. En conséquence, la tentative de modifier ces champs a conduit à un échec silencieux — les valeurs restaient inchangées, et le bug n'a pas été découvert pendant longtemps.


Histoire

Lors de la migration vers Java 8, les développeurs ont ajouté des méthodes avec des implémentations dans l'interface, mais ont oublié de prendre en compte que certaines classes héritaient également de méthodes homonymes via une classe abstraite. Cela a conduit à des conflits de méthodes et à des résultats inattendus lors de la résolution de l'héritage.