Pourquoi une classe abstraite implémentant une interface peut-elle manquer la déclaration / implémentation d’une des méthodes de l’interface?

Une chose curieuse se produit en Java lorsque vous utilisez une classe abstraite pour implémenter une interface: certaines méthodes de l’interface peuvent être complètement manquantes (c’est-à-dire qu’aucune déclaration abstraite ou implémentation réelle n’est présente), mais le compilateur ne s’en plaint pas.

Par exemple, compte tenu de l’interface:

public interface IAnything { void m1(); void m2(); void m3(); } 

la classe abstraite suivante est compilée sans avertissement ni erreur:

 public abstract class AbstractThing implements IAnything { public void m1() {} public void m3() {} } 

Pouvez-vous expliquer pourquoi?

En effet, si une classe est abstraite, alors, par définition, vous devez en créer des sous-classes pour l’instancier. Les sous-classes seront requirejses (par le compilateur) pour implémenter toutes les méthodes d’interface que la classe abstraite a laissées de côté.

En suivant votre exemple de code, essayez de créer une sous-classe de AbstractThing sans implémenter la méthode m2 et voyez quelles erreurs le compilateur vous donne. Cela vous obligera à implémenter cette méthode.

Parfaitement bien.
Vous ne pouvez pas instancier des classes abstraites .. mais les classes abstraites peuvent être utilisées pour héberger des implémentations courantes pour m1 () et m3 ().
Donc, si la mise en œuvre de m2 () est différente pour chaque implémentation, m1 et m3 ne le sont pas. Vous pouvez créer différentes implémentations IAnything concrètes avec les différentes implémentations m2 et dériver de AbstractThing – en respectant le principe DRY. Valider si l’interface est complètement implémentée pour une classe abstraite est futile ..

Mise à jour : Fait intéressant, je trouve que C # applique ceci comme une erreur de compilation. Vous êtes obligé de copier les signatures de la méthode et de les préfixer avec ‘public abstrait’ dans la classe de base abstraite de ce scénario .. (quelque chose de nouveau tous les jours 🙂

C’est très bien. Pour comprendre ce qui précède, vous devez d’abord comprendre la nature des classes abstraites. Ils sont similaires aux interfaces à cet égard. C’est ce que dit Oracle à ce sujet ici .

Les classes abstraites sont similaires aux interfaces. Vous ne pouvez pas les instancier et ils peuvent contenir un mélange de méthodes déclarées avec ou sans implémentation.

Vous devez donc penser à ce qui se passe lorsqu’une interface étend une autre interface. Par exemple …

 //Filename: Sports.java public interface Sports { public void setHomeTeam(Ssortingng name); public void setVisitingTeam(Ssortingng name); } //Filename: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } 

… comme vous pouvez le voir, cela comstack parfaitement. Tout simplement parce que, tout comme une classe abstraite, une interface ne peut PAS être instanciée. Il n’est donc pas nécessaire de mentionner explicitement les méthodes de son “parent”. Cependant, TOUTES les signatures de la méthode parente deviennent implicitement une partie de l’interface d’extension ou de la classe abstraite d’implémentation. Ainsi, une fois qu’une classe appropriée (une classe pouvant être instanciée) étend ce qui précède, il faudra s’assurer que chaque méthode abstraite est implémentée.

J’espère que ça aide … et Allahou ‘alam!

Interface désigne une classe qui n’a pas d’implémentation de sa méthode, mais avec une simple déclaration.
D’autre part, la classe abstraite est une classe qui peut avoir une implémentation d’une méthode avec une méthode avec une simple déclaration, sans implémentation.
Lorsque nous implémentons une interface dans une classe abstraite, cela signifie que la classe abstraite a hérité de toutes les méthodes de l’interface. Comme, il n’est pas important d’implémenter toute la méthode dans la classe abstraite mais cela concerne la classe abstraite (par inheritance aussi), donc la classe abstraite peut laisser une partie de la méthode en interface sans implémentation ici. Mais, lorsque cette classe abstraite héritera d’une classe concrète, elle devra implémenter toutes les méthodes non implémentées dans la classe abstraite.

Quand une classe abstraite implémente une interface

Dans la section sur les interfaces, il a été noté qu’une classe qui implémente une interface doit implémenter toutes les méthodes de l’interface. Il est toutefois possible de définir une classe qui n’implémente pas toutes les méthodes de l’interface, à condition que la classe soit déclarée abstraite. Par exemple,

 abstract class X implements Y { // implements all but one method of Y } 
 class XX extends X { // implements the remaining method in Y } 

Dans ce cas, la classe X doit être abstraite car elle n’implémente pas complètement Y, mais la classe XX implémente en fait Y.

Référence: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Les classes abstraites ne sont pas nécessaires pour implémenter les méthodes. Donc, même si elle implémente une interface, les méthodes abstraites de l’interface peuvent restr abstraites. Si vous essayez d’implémenter une interface dans une classe concrète (c’est-à-dire non abstraite) et que vous n’implémentez pas les méthodes abstraites, le compilateur vous dira: Implémentez les méthodes abstraites ou déclarez la classe comme abstraite.

Vu l’interface:

 public interface IAnything { int i; void m1(); void m2(); void m3(); } 

Voici comment Java le voit:

 public interface IAnything { public static final int i; public abstract void m1(); public abstract void m2(); public abstract void m3(); } 

Vous pouvez donc laisser certaines de ces méthodes abstract non implémentées, comme vous le feriez dans le cas de classes abstract étendent une autre classe abstract .

Lorsque vous implement une interface , la règle selon laquelle toutes interface méthodes d’ interface doivent être implémentées dans la class dérivée, s’applique uniquement à l’implémentation de class concrète (c’est-à-dire qui n’est pas abstract elle-même).

Si vous prévoyez de créer une abstract class , il n’y a pas de règle indiquant que vous devez implement toutes les méthodes d’ interface (notez que dans un tel cas, il est obligatoire de déclarer la class dérivée comme abstract )