La question est en Java, pourquoi ne puis-je pas définir une méthode statique abstraite? par exemple
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
La question est en Java, pourquoi ne puis-je pas définir une méthode statique abstraite? par exemple
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
Réponses:
Parce que "abstrait" signifie: "n'implémente aucune fonctionnalité" et "statique" signifie: "il y a une fonctionnalité même si vous n'avez pas d'instance d'objet". Et c'est une contradiction logique.
la source
abstract static
aurait un sens parfait. Ce serait une méthode de l'objet de classe lui-même que les objets de sous-classe doivent implémenter. Bien sûr, la façon dont les choses se présentent, votre réponse est correcte malgré mon emprise sur la langue.abstract static
: Une fonction X qui est "implémentée dans la sous-classe" ne peut pas en même temps "être exécutée sur la classe" - uniquement sur la sous - classe . Là où il n'est alors plus abstrait.static
ne signifie pas "pas vide" - c'est juste une conséquence de Java qui ne permet pas aux méthodes statiques d'être abstraites. Cela signifie "appelable sur la classe". (Cela devrait signifier "appelable uniquement sur la classe" mais c'est un autre problème.) Si lesabstract static
méthodes prises en charge par Java , je m'attendrais à ce que cela signifie que la méthode 1) doit être implémentée par des sous-classes, et 2) est une méthode de classe de la sous-classe. Certaines méthodes n'ont tout simplement pas de sens en tant que méthodes d'instance. Malheureusement, Java ne vous permet pas de spécifier cela lors de la création d'une classe de base abstraite (ou d'une interface).Mauvaise conception de la langue. Il serait beaucoup plus efficace d'appeler directement une méthode abstraite statique que de créer une instance uniquement pour utiliser cette méthode abstraite. Cela est particulièrement vrai lorsque vous utilisez une classe abstraite comme solution de contournement pour l'incapacité d'énumération à s'étendre, ce qui est un autre exemple de conception médiocre. J'espère qu'ils résoudront ces limitations dans une prochaine version.
la source
static
lui-même est déjà une violation ....Vous ne pouvez pas remplacer une méthode statique, donc la rendre abstraite n'aurait aucun sens. De plus, une méthode statique dans une classe abstraite appartiendrait à cette classe, et non à la classe prioritaire, elle ne pourrait donc pas être utilisée de toute façon.
la source
L'
abstract
annotation à une méthode indique que la méthode DOIT être remplacée dans une sous-classe.En Java, un
static
membre (méthode ou champ) ne peut pas être remplacé par des sous-classes (ce n'est pas nécessairement vrai dans d'autres langages orientés objet, voir SmallTalk.) Unstatic
membre peut être masqué , mais cela est fondamentalement différent du remplacement .Étant donné que les membres statiques ne peuvent pas être remplacés dans une sous-classe, l'
abstract
annotation ne peut pas leur être appliquée.En passant, d'autres langages prennent en charge l'héritage statique, tout comme l'héritage d'instance. Du point de vue de la syntaxe, ces langages nécessitent généralement que le nom de la classe soit inclus dans l'instruction. Par exemple, en Java, en supposant que vous écrivez du code dans ClassA, ce sont des instructions équivalentes (si methodA () est une méthode statique et qu'il n'y a pas de méthode d'instance avec la même signature):
et
Dans SmallTalk, le nom de classe n'est pas facultatif, donc la syntaxe est (notez que SmallTalk n'utilise pas le. Pour séparer le "sujet" et le "verbe", mais l'utilise à la place comme terminateur de statemend):
Étant donné que le nom de classe est toujours requis, la "version" correcte de la méthode peut toujours être déterminée en parcourant la hiérarchie des classes. Pour ce que ça vaut, je manque parfois l'
static
héritage, et j'ai été mordu par le manque d'héritage statique en Java lorsque j'ai commencé avec. De plus, SmallTalk est de type canard (et ne prend donc pas en charge le programme par contrat.) Ainsi, il n'a pas deabstract
modificateur pour les membres de la classe.la source
J'ai aussi posé la même question, voici pourquoi
Puisque la classe Abstract dit, elle ne donnera pas d'implémentation et permettra à la sous-classe de la donner
donc Subclass doit remplacer les méthodes de Superclass,
RÈGLE NO 1 - Une méthode statique ne peut pas être remplacée
Étant donné que les membres et les méthodes statiques sont des éléments de temps de compilation, c'est pourquoi la surcharge (polymorphisme de compilation) des méthodes statiques est autorisée plutôt que la substitution (polymorphisme d'exécution)
Donc, ils ne peuvent pas être abstraits.
Il n'y a rien de tel que l' abstrait statique <--- Non autorisé dans Java Universe
la source
abstract static
voir stackoverflow.com/questions/370962/… . La vraie raison pour laquelle Java n'autorise pas le remplacement des méthodes statiques est que Java n'autorise pas le remplacement des méthodes statiques.foo(String)
n'est donc pas la même chose quefoo(Integer)
- c'est tout.C'est une conception de langage terrible et vraiment aucune raison pour laquelle cela ne peut pas être possible.
En fait, voici une implémentation sur la façon dont cela PEUT être fait dans JAVA :
================= Ancien exemple ci-dessous =================
Recherchez getRequest, et getRequestImpl ... setInstance peut être appelé pour modifier l'implémentation avant l'appel.
Utilisé comme suit:
la source
abstract static
méthode comme demandé dans la question et vous avez écrit en gras CAN BE DONE IN JAVA . C'est complètement erroné.Une méthode abstraite n'est définie que pour pouvoir être remplacée dans une sous-classe. Cependant, les méthodes statiques ne peuvent pas être remplacées. Par conséquent, c'est une erreur de compilation d'avoir une méthode abstraite et statique.
Maintenant, la question suivante est de savoir pourquoi les méthodes statiques ne peuvent pas être remplacées.
C'est parce que les méthodes statiques appartiennent à une classe particulière et non à son instance. Si vous essayez de remplacer une méthode statique, vous n'obtiendrez aucune erreur de compilation ou d'exécution, mais le compilateur masquera simplement la méthode statique de superclasse.
la source
Une méthode statique, par définition, n'a pas besoin de savoir
this
. Ainsi, il ne peut pas s'agir d'une méthode virtuelle (qui est surchargée en fonction des informations de sous-classe dynamique disponibles viathis
); au lieu de cela, une surcharge de méthode statique est uniquement basée sur les informations disponibles au moment de la compilation (cela signifie: une fois que vous référez une méthode statique de superclasse, vous appelez notamment la méthode de superclasse, mais jamais une méthode de sous-classe).Selon cela, les méthodes statiques abstraites seraient tout à fait inutiles car vous n'aurez jamais sa référence substituée par un corps défini.
la source
Je vois qu'il y a déjà un dieu-zillion de réponses mais je ne vois pas de solutions pratiques. Bien sûr, c'est un vrai problème et il n'y a aucune bonne raison d'exclure cette syntaxe en Java. Étant donné que la question d'origine manque de contexte où cela peut être nécessaire, je fournis à la fois un contexte et une solution:
Supposons que vous ayez une méthode statique dans un groupe de classes identiques. Ces méthodes appellent une méthode statique spécifique à la classe:
doWork()
dansC1
etC2
sont identiques. Il peut y avoir beaucoup de ces calsses:C3
C4
etc. Sistatic abstract
c'était autorisé, vous élimineriez le code en double en faisant quelque chose comme:mais cela ne compilerait pas car la
static abstract
combinaison n'est pas autorisée. Cependant, cela peut être contourné avec lastatic class
construction, ce qui est autorisé:Avec cette solution, le seul code dupliqué est
la source
C1.doWork()
ouC2.doWork()
Mais vous ne pouvez pas appelerC.doWork()
. Toujours dans l'exemple que vous avez fourni, qui ne fonctionnera pas, supposez que cela ait été autorisé, alors comment la classeC
trouvera-t-elle l'implémentation dedoMoreWork()
? Enfin, j'appellerais votre code de contexte une mauvaise conception. Pourquoi? tout simplement parce que vous avez créé une fonction distincte pour le code qui est unique au lieu de créer une fonction pour le code qui est commun, puis d'implémenter une fonction statique dans la classeC
. C'est plus facile !!!Supposons qu'il existe deux classes,
Parent
etChild
.Parent
estabstract
. Les déclarations sont les suivantes:Cela signifie que toute instance de
Parent
doit spécifier commentrun()
est exécutée.Cependant, supposez maintenant que ce
Parent
n'est pas le casabstract
.Cela signifie que
Parent.run()
va exécuter la méthode statique.La définition d'une
abstract
méthode est "Une méthode déclarée mais non implémentée", ce qui signifie qu'elle ne retourne rien elle-même.La définition d'une
static
méthode est "Une méthode qui renvoie la même valeur pour les mêmes paramètres quelle que soit l'instance sur laquelle elle est appelée".abstract
La valeur de retour d' une méthode change à mesure que l'instance change. Unestatic
méthode ne le fera pas. Unestatic abstract
méthode est à peu près une méthode où la valeur de retour est constante, mais ne renvoie rien. C'est une contradiction logique.De plus, il n'y a vraiment pas beaucoup de raison pour une
static abstract
méthode.la source
Une classe abstraite ne peut pas avoir de méthode statique car l'abstraction est effectuée pour obtenir une LIAISON DYNAMIQUE alors que les méthodes statiques sont liées statiquement à leur fonctionnalité.Une méthode statique signifie un comportement ne dépendant pas d'une variable d'instance, donc aucune instance / objet n'est requis.Juste la classe. Les méthodes statiques appartiennent à la classe et non à l'objet. Ils sont stockés dans une zone mémoire appelée PERMGEN d'où ils sont partagés avec chaque objet. Les méthodes de la classe abstraite sont liées dynamiquement à leur fonctionnalité.
la source
Déclarer une méthode
static
signifie que nous pouvons l'appeler par son nom de classe et si cette classe l'estabstract
également, cela n'a aucun sens de l'appeler car elle ne contient aucun corps, et donc nous ne pouvons pas déclarer une méthode à la fois commestatic
etabstract
.la source
Comme les méthodes abstraites appartiennent à la classe et ne peuvent pas être remplacées par la classe d'implémentation, même s'il existe une méthode statique avec la même signature, elle masque la méthode, ne la remplace pas. Il est donc indifférent de déclarer la méthode abstraite comme statique car elle n'obtiendra jamais le corps. Ainsi, compiler l'erreur de temps.
la source
Une méthode statique peut être appelée sans instance de la classe. Dans votre exemple, vous pouvez appeler foo.bar2 (), mais pas foo.bar (), car pour bar, vous avez besoin d'une instance. Le code suivant fonctionnerait:
Si vous appelez une méthode statique, elle sera toujours exécutée avec le même code. Dans l'exemple ci-dessus, même si vous redéfinissez bar2 dans ImplementsFoo, un appel à var.bar2 () exécuterait foo.bar2 ().
Si bar2 n'a maintenant aucune implémentation (c'est ce que signifie abstrait), vous pouvez appeler une méthode sans implémentation. C'est très dangereux.
la source
Je crois avoir trouvé la réponse à cette question, sous la forme de pourquoi les méthodes d'une interface (qui fonctionnent comme des méthodes abstraites dans une classe parente) ne peuvent pas être statiques. Voici la réponse complète (pas la mienne)
Les méthodes essentiellement statiques peuvent être liées au moment de la compilation, car pour les appeler, vous devez spécifier une classe. Ceci est différent des méthodes d'instance, pour lesquelles la classe de la référence à partir de laquelle vous appelez la méthode peut être inconnue au moment de la compilation (ainsi, quel bloc de code est appelé ne peut être déterminé qu'au moment de l'exécution).
Si vous appelez une méthode statique, vous connaissez déjà la classe où elle est implémentée, ou ses sous-classes directes. Si vous définissez
Ensuite, tout
Foo.bar();
appel est évidemment illégal et vous l'utiliserez toujoursFoo2.bar();
.Dans cet esprit, le seul but d'une méthode abstraite statique serait d'imposer des sous-classes pour implémenter une telle méthode. Vous pourriez initialement penser que c'est TRÈS faux, mais si vous avez un paramètre de type générique,
<E extends MySuperClass>
ce serait bien de garantir via une interface qui leE
peut.doSomething()
. Gardez à l'esprit qu'en raison du type d'effacement, les génériques n'existent qu'au moment de la compilation.Alors, serait-ce utile? Oui, et c'est peut-être pour cela que Java 8 autorise les méthodes statiques dans les interfaces (mais uniquement avec une implémentation par défaut). Pourquoi pas des méthodes statiques abstraites avec une implémentation par défaut dans les classes? Tout simplement parce qu'une méthode abstraite avec une implémentation par défaut est en fait une méthode concrète.
Pourquoi pas des méthodes statiques abstraites / d'interface sans implémentation par défaut? Apparemment, simplement à cause de la façon dont Java identifie le bloc de code à exécuter (première partie de ma réponse).
la source
Parce que la classe abstraite est un concept OOPS et que les membres statiques ne font pas partie d'OOPS ....
Maintenant, le problème est que nous pouvons déclarer des méthodes complètes statiques dans l'interface et nous pouvons exécuter l'interface en déclarant la méthode principale à l'intérieur d'une interface
la source
L'idée d'avoir une méthode statique abstraite serait que vous ne pouvez pas utiliser cette classe abstraite particulière directement pour cette méthode, mais seule la dérivée première serait autorisée à implémenter cette méthode statique (ou pour les génériques: la classe réelle du générique vous utilisation).
De cette façon, vous pouvez créer par exemple une classe abstraite sortableObject ou même une interface avec des méthodes statiques (auto-) abstraites, qui définit les paramètres des options de tri:
Vous pouvez maintenant définir un objet triable qui peut être trié par les principaux types qui sont les mêmes pour tous ces objets:
Vous pouvez maintenant créer un
qui peut récupérer les types, créer un menu contextuel pour sélectionner un type sur lequel trier et recourir à la liste en obtenant les données de ce type, ainsi que disposer d'une fonction d'ajout qui, lorsqu'un type de tri a été sélectionné, peut automatiquement -sort les nouveaux éléments. Notez que l'instance de SortableList peut accéder directement à la méthode statique de "T":
Le problème lié à l'utilisation d'une instance est que la SortableList peut ne pas encore contenir d'éléments, mais doit déjà fournir le tri préféré.
Cheerio, Olaf.
la source
Tout d'abord, un point clé sur les classes abstraites - Une classe abstraite ne peut pas être instanciée (voir wiki ). Vous ne pouvez donc pas créer d' instance d'une classe abstraite.
Maintenant, la façon dont java traite les méthodes statiques consiste à partager la méthode avec toutes les instances de cette classe.
Donc, si vous ne pouvez pas instancier une classe, cette classe ne peut pas avoir de méthodes statiques abstraites car une méthode abstraite demande à être étendue.
Boom.
la source
Selon le document Java :
En Java 8, avec les méthodes par défaut, les méthodes statiques sont également autorisées dans une interface. Cela nous permet d'organiser plus facilement les méthodes d'assistance dans nos bibliothèques. Nous pouvons conserver des méthodes statiques spécifiques à une interface dans la même interface plutôt que dans une classe distincte.
Un bel exemple de ceci est:
au lieu de
Un autre exemple d'utilisation de méthodes statiques est également donné dans la doc elle-même:
la source
Parce que «abstrait» signifie que la méthode est censée être remplacée et que l'on ne peut pas remplacer les méthodes «statiques».
la source
Les méthodes régulières peuvent être abstraites lorsqu'elles sont censées être remplacées par des sous-classes et dotées de fonctionnalités. Imaginez que la classe
Foo
soit étendue parBar1, Bar2, Bar3
etc. Ainsi, chacun aura sa propre version de la classe abstraite en fonction de ses besoins.Or, les méthodes statiques appartiennent par définition à la classe, elles n'ont rien à voir avec les objets de la classe ou les objets de ses sous-classes. Ils n'en ont même pas besoin pour exister, ils peuvent être utilisés sans instancier les classes. Par conséquent, ils doivent être prêts à l'emploi et ne peuvent pas dépendre des sous-classes pour leur ajouter des fonctionnalités.
la source
Parce que l'abstrait est un mot-clé appliqué aux méthodes abstraites, ne spécifiez pas de corps. Et si nous parlons de mot-clé statique, il appartient à la zone de classe.
la source
car si vous utilisez un membre statique ou une variable statique dans la classe, il se chargera au moment du chargement de la classe.
la source
Vous pouvez le faire avec des interfaces dans Java 8.
Voici la documentation officielle à ce sujet:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
la source
Parce que si une classe étend une classe abstraite, elle doit remplacer les méthodes abstraites et c'est obligatoire. Et puisque les méthodes statiques sont des méthodes de classe résolues au moment de la compilation alors que les méthodes remplacées sont des méthodes d'instance résolues au moment de l'exécution et après le polymorphisme dynamique.
la source