Pourquoi les méthodes abstraites doivent-elles être implémentées par la première classe concrète et non par une autre en bas de la chaîne?

Je suis curieux de savoir pourquoi les méthodes abstraites DOIVENT être écrasées par la première classe d’implémentation concrète et non par une modification ultérieure de la hiérarchie.

Je ne suggère pas que je veux faire cela, mais je suis curieux de savoir pourquoi ce doit être la première classe

Considérez cet exemple

abstract class Upper { abstract void doSomething(); } class Middle extends Upper { void doSomething() { // I'm forced to be implemented here } } abstract class Lower extends Middle { } class Bottom extends Lower { void doSomething() { // I'm valid, but I'm too far down the hierarchy } } 

Par définition, une classe normale doit implémenter toutes les méthodes abstraites. Si vous déclariez Middle abstract, vous n’auriez pas à implémenter les méthodes dans Middle.

Une classe normale peut être instanciée, alors qu’une classe abstraite ne le peut pas. Réfléchissez à ce qui arriverait si vous essayez d’appeler les méthodes qui ne sont pas implémentées dans la classe.

les classes concrètes sont concrètes.
Ce qui signifie qu’ils devraient pouvoir être initialisés et utilisés.
Donc, si vous n’implémentez pas les méthodes, comment les utiliser correctement? ce sera incomplet et donc pas concret.

Vous pouvez faire en sorte qu’une autre classe abstraite hérite d’une classe abstraite.

Faites juste du Middle un cours abstrait, et c’est bien.

Si vous souhaitez conserver Middle comme classe concrète tout en supprimant doSomething à faire, expliquez ce que vous souhaitez que ce code fasse:

 Upper x = new Middle(); x.doSomething(); 

Si Middle est une classe concrète, une version instanciée qui ne définit pas de méthode abstraite ne serait pas appelable (car elle n’a pas de définition). Cela ferait de manière inhérente à Middle une classe abstraite également.

Parce que vous ne pouvez pas avoir de méthodes abstraites dans une classe qui n’est pas abstraite. Si vous ne souhaitez pas utiliser l’une des méthodes, vous n’avez pas besoin d’étendre cette classe.

Au lieu de cela, juste avoir la class Lower extend Upper .

Si vous souhaitez toujours que Lower hérite à la fois des méthodes abstraites et de Middle , déclarez simplement Middle comme abstrait.

Vous êtes obligé d’implémenter doSomething in Middle , car Middle est une classe concrète. Cela signifie que Middle doit fournir une implémentation de toutes les méthodes abstraites de sa super-classe, ainsi qu’une implémentation de toutes les méthodes d’interface des interfaces qu’il implémente.

Si vous avez sélectionné Middle tant que classe abstraite, vous pouvez déléguer l’implémentation de doSomething à Bottom .

Pour plus d’informations sur les classes abstraites, voir ce lien à partir de la spécification du langage Java .

Dans votre exemple sans la déclaration de doSomething au milieu, il n’y aurait aucun code à exécuter. Par conséquent, la classe devrait être abstraite.

Ce n’est pas vraiment une question de must . Une classe abstraite est juste une classe avec une ou plusieurs méthodes sans implémentation.

C’est plus comme dire qu’un homme humain biologique doit avoir un chromosome Y. Ce n’est pas une loi; cela fait juste partie de la définition.

Dans votre exemple, si vous ne voulez pas mettre en œuvre doSomething in Middle , vous ne voulez vraiment pas que Middle soit concret . C’est-à-dire qu’il y aurait une méthode qui n’a pas de définition. Donc c’est abstrait.

Vous pouvez bien sûr l’implémenter comme une fonction vide qui ne fait rien. C’est assez proche de ce que vous demandez, je crois.

Vraiment, c’est juste une question de terminologie. S’il y a des membres non implémentés, alors l’abrégé du type. C’est si simple.