Pourquoi les classes Java ne peuvent-elles pas avoir de champs abstraits comme elles peuvent avoir des méthodes abstraites?
Par exemple: j'ai deux classes qui étendent la même classe de base abstraite. Ces deux classes ont chacune une méthode identique à l'exception d'une constante String, qui se trouve être un message d'erreur, en leur sein. Si les champs pouvaient être abstraits, je pourrais créer cette constante abstraite et faire remonter la méthode dans la classe de base. Au lieu de cela, je dois créer une méthode abstraite, appelée getErrMsg()
dans ce cas, qui renvoie la chaîne, remplacer cette méthode dans les deux classes dérivées, puis je peux extraire la méthode (qui appelle maintenant la méthode abstraite).
Pourquoi ne pourrais-je pas simplement faire le champ abstrait pour commencer? Java aurait-il été conçu pour permettre cela?
Réponses:
Vous pouvez faire ce que vous avez décrit en ayant un champ final dans votre classe abstraite qui est initialisé dans son constructeur (code non testé):
Si votre classe enfant "oublie" d'initialiser la finale via le super constructeur, le compilateur donnera
un avertissement etune erreur, tout comme lorsqu'une méthode abstraite n'est pas implémentée.la source
Base
faut le déclarerabstract
.Je ne vois aucun intérêt à cela. Vous pouvez déplacer la fonction vers la classe abstraite et simplement remplacer un champ protégé. Je ne sais pas si cela fonctionne avec des constantes mais l'effet est le même:
Donc, votre point est que vous voulez appliquer l'implémentation / le remplacement / quoi que ce soit
errorMsg
dans les sous-classes? Je pensais que vous vouliez juste avoir la méthode dans la classe de base et que vous ne saviez pas comment gérer le champ à ce moment-là.la source
protected String errorMsg;
ce qui impose d'une manière ou d'une autre que je définis la valeur dans les sous-classes. Il est similaire à ces classes abstraites qui implémentent en fait toutes les méthodes en tant qu'espaces réservés afin que les développeurs n'aient pas à implémenter chaque méthode même s'ils n'en ont pas besoin.protected String errorMsg;
n'impose pas que vous définissiez la valeur dans les sous-classes.Évidemment, il aurait pu être conçu pour permettre cela, mais sous les couvertures, il devrait encore faire une répartition dynamique, et donc un appel de méthode. La conception de Java (du moins dans les premiers jours) était, dans une certaine mesure, une tentative d'être minimaliste. Autrement dit, les concepteurs ont essayé d'éviter d'ajouter de nouvelles fonctionnalités si elles pouvaient être facilement simulées par d'autres fonctionnalités déjà présentes dans le langage.
la source
En lisant votre titre, je pensais que vous faisiez référence aux membres de l'instance abstraite; et je ne voyais pas beaucoup d’utilité pour eux. Mais les membres statiques abstraits sont une tout autre affaire.
J'ai souvent souhaité pouvoir déclarer une méthode comme la suivante en Java:
Fondamentalement, je voudrais insister sur le fait que les implémentations concrètes de ma classe parente fournissent une méthode de fabrique statique avec une signature spécifique. Cela me permettrait d'obtenir une référence à une classe concrète avec
Class.forName()
et d'être certain que je pourrais en construire une dans une convention de mon choix.la source
@autowired T fieldName
. SiT
est défini comme quelque chose commeT extends AbstractController
, l'effacement de type provoque la génération du champ en tant que typeAbstractController
et qui ne peut pas être câblé automatiquement car il n'est ni concret ni unique. Je suis généralement d'accord pour dire qu'ils ne sont pas très utiles et qu'ils n'appartiennent donc pas à la langue. Ce avec quoi je ne suis pas d'accord, c'est qu'il n'y a AUCUNE utilité pour eux.Une autre option consiste à définir le champ comme public (final, si vous le souhaitez) dans la classe de base, puis à initialiser ce champ dans le constructeur de la classe de base, en fonction de la sous-classe actuellement utilisée. C'est un peu louche, en ce sens qu'il introduit une dépendance circulaire. Mais, au moins, ce n'est pas une dépendance qui peut jamais changer - c'est-à-dire que la sous-classe existera ou n'existera pas, mais les méthodes ou les champs de la sous-classe ne peuvent pas influencer la valeur de
field
.la source