Pourquoi n'est-il pas possible de remplacer les méthodes statiques?
Si possible, veuillez utiliser un exemple.
java
static
overriding
static-methods
sgokhales
la source
la source
Parent p = new Child()
et quep.childOverriddenStaticMethod()
le compilateur le résoudraParent.childOverriddenStaticMethod()
en regardant le type de référence.Réponses:
La substitution dépend de la présence d'une instance d'une classe. Le point de polymorphisme est que vous pouvez sous-classer une classe et les objets implémentant ces sous-classes auront des comportements différents pour les mêmes méthodes définies dans la superclasse (et remplacées dans les sous-classes). Une méthode statique n'est associée à aucune instance d'une classe, le concept n'est donc pas applicable.
Il y avait deux considérations guidant la conception de Java qui ont eu un impact sur cela. L'un était un problème de performances: il y avait eu beaucoup de critiques à propos de Smalltalk sur le fait qu'il était trop lent (la collecte des ordures et les appels polymorphes en faisaient partie) et les créateurs de Java étaient déterminés à éviter cela. Une autre décision a été que le public cible de Java était les développeurs C ++. Faire fonctionner les méthodes statiques de la façon dont elles fonctionnaient avait l'avantage d'être familier pour les programmeurs C ++ et était également très rapide, car il n'est pas nécessaire d'attendre le temps d'exécution pour déterminer quelle méthode appeler.
la source
objects
) permet la surcharge des méthodes.obj.staticMethod()
) - ce qui est autorisé et utilise les types au moment de la compilation. Lorsque l'appel statique se trouve dans une méthode non statique d'une classe, l'objet "courant" peut être un type dérivé de la classe - mais les méthodes statiques définies sur les types dérivés ne sont pas prises en compte (elles sont dans le type d'exécution hiérarchie).Personnellement, je pense que c'est une faille dans la conception de Java. Oui, oui, je comprends que les méthodes non statiques sont attachées à une instance tandis que les méthodes statiques sont attachées à une classe, etc. etc. Toujours considérer le code suivant:
Ce code ne fonctionnera pas comme vous pouvez vous y attendre. À savoir, SpecialEmployee obtient un bonus de 2% tout comme les employés réguliers. Mais si vous supprimez les "statiques", alors SpecialEmployee obtient un bonus de 3%.
(Certes, cet exemple est un mauvais style de codage dans la mesure où, dans la vraie vie, vous voudriez probablement que le multiplicateur de bonus soit dans une base de données quelque part plutôt que codé en dur. Mais c'est simplement parce que je ne voulais pas embêter l'exemple avec beaucoup de code hors de propos.)
Il me semble tout à fait plausible que vous souhaitiez rendre statique getBonusMultiplier. Vous souhaitez peut-être pouvoir afficher le multiplicateur de bonus pour toutes les catégories d'employés, sans avoir besoin d'avoir une instance d'un employé dans chaque catégorie. Quel serait l'intérêt de rechercher de tels exemples? Que se passe-t-il si nous créons une nouvelle catégorie d'employés et qu'aucun employé ne lui est encore affecté? Il s'agit logiquement d'une fonction statique.
Mais ça ne marche pas.
Et oui, oui, je peux penser à un certain nombre de façons de réécrire le code ci-dessus pour le faire fonctionner. Mon point n'est pas qu'il crée un problème insoluble, mais qu'il crée un piège pour le programmeur imprudent, car le langage ne se comporte pas comme je pense qu'une personne raisonnable pourrait s'y attendre.
Peut-être que si j'essayais d'écrire un compilateur pour un langage OOP, je verrais rapidement pourquoi l'implémenter afin que les fonctions statiques puissent être remplacées serait difficile, voire impossible.
Ou peut-être y a-t-il une bonne raison pour laquelle Java se comporte de cette façon. Quelqu'un peut-il signaler un avantage à ce comportement, une catégorie de problème facilitée par cela? Je veux dire, ne me pointez pas simplement vers la spécification du langage Java et dites "voyez, c'est documenté comment ça se comporte". Je le sais. Mais y a-t-il une bonne raison pour laquelle il DEVRAIT se comporter de cette façon? (En plus de l'évidence "faire fonctionner correctement était trop difficile" ...)
Mise à jour
@VicKirk: Si vous voulez dire qu'il s'agit d'une "mauvaise conception" car elle ne correspond pas à la façon dont Java gère la statique, ma réponse est "Eh bien, duh, bien sûr." Comme je l'ai dit dans mon article d'origine, cela ne fonctionne pas. Mais si vous voulez dire que c'est une mauvaise conception dans le sens où il y aurait quelque chose de fondamentalement mauvais avec un langage où cela fonctionne, c'est-à-dire où la statique pourrait être remplacée tout comme les fonctions virtuelles, que cela introduirait en quelque sorte une ambiguïté ou qu'il serait impossible de mettre en œuvre efficacement ou certains, je réponds: "Pourquoi? Quel est le problème avec le concept?"
Je pense que l'exemple que je donne est une chose très naturelle à vouloir faire. J'ai une classe qui a une fonction qui ne dépend d'aucune donnée d'instance, et que je pourrais très raisonnablement vouloir appeler indépendamment d'une instance, ainsi que vouloir appeler à partir d'une méthode d'instance. Pourquoi cela ne fonctionnerait-il pas? J'ai rencontré cette situation un bon nombre de fois au fil des ans. En pratique, je la contourne en rendant la fonction virtuelle, puis en créant une méthode statique dont le seul but dans la vie est d'être une méthode statique qui transmet l'appel à la méthode virtuelle avec une instance factice. Cela semble être un moyen très détourné pour y arriver.
la source
someStatic()
et B étend A, puisB.someMethod()
se lie à la méthode en A. Si j'ajoute ensuitesomeStatic()
à B, le code appelant invoque toujoursA.someStatic()
jusqu'à ce que je recompile le code appelant. De plus, cela m'a surpris d'bInstance.someStatic()
utiliser le type déclaré de bInstance, pas le type d'exécution car il se lie à la compilation et non au lien,A bInstance; ... bInstance.someStatic()
invoque donc A.someStatic () si si B.someStatic () existe.La réponse courte est: c'est tout à fait possible, mais Java ne le fait pas.
Voici un code qui illustre l' état actuel des choses à Java:
Fichier
Base.java
:Fichier
Child.java
:Si vous exécutez ceci (je l'ai fait sur un Mac, depuis Eclipse, en utilisant Java 1.6), vous obtenez:
Ici, les seuls cas qui pourraient être une surprise (et sur lesquels porte la question) semblent être le premier cas:
"Le type d'exécution n'est pas utilisé pour déterminer quelles méthodes statiques sont appelées, même lorsqu'il est appelé avec une instance d'objet (
obj.staticMethod()
)."et le dernier cas:
"Lors de l'appel d'une méthode statique à partir d'une méthode objet d'une classe, la méthode statique choisie est celle accessible depuis la classe elle-même et non depuis la classe définissant le type d'exécution de l'objet."
Appel avec une instance d'objet
L'appel statique est résolu au moment de la compilation, tandis qu'un appel de méthode non statique est résolu au moment de l'exécution. Notez que bien que les méthodes statiques soient héritées (du parent), elles ne sont pas remplacées (par l'enfant). Cela pourrait être une surprise si vous vous attendiez à autre chose.
Appel depuis une méthode objet
Les appels de méthode objet sont résolus à l'aide du type d'exécution, mais les appels de méthode statique ( classe ) sont résolus à l'aide du type de compilation (déclaré).
Changer les règles
Pour modifier ces règles, de sorte que le dernier appel dans l'exemple appelé
Child.printValue()
, les appels statiques doivent être fournis avec un type au moment de l'exécution, plutôt que le compilateur résolvant l'appel au moment de la compilation avec la classe déclarée de l'objet (ou le contexte). Les appels statiques pourraient alors utiliser la hiérarchie de type (dynamique) pour résoudre l'appel, tout comme les appels de méthode objet le font aujourd'hui.Cela serait facilement réalisable (si nous changions Java: -O), et ce n'est pas du tout déraisonnable, cependant, cela a quelques considérations intéressantes.
La considération principale est que nous devons décider quels appels de méthodes statiques devraient faire cela.
À l'heure actuelle, Java a cette "bizarrerie" dans le langage où les
obj.staticMethod()
appels sont remplacés par desObjectClass.staticMethod()
appels (normalement avec un avertissement). [ Remarque:ObjectClass
est le type de compilationobj
.] Ce sont de bons candidats pour remplacer de cette manière, en prenant le type d'exécution deobj
.Si nous le faisions, cela rendrait les corps de méthodes plus difficiles à lire: les appels statiques dans une classe parente pourraient potentiellement être "réacheminés" dynamiquement . Pour éviter cela, nous devrions appeler la méthode statique avec un nom de classe - et cela rend les appels résolus de manière plus évidente avec la hiérarchie de type à la compilation (comme maintenant).
Les autres façons d'invoquer une méthode statique sont plus délicates:
this.staticMethod()
devraient signifier la même chose queobj.staticMethod()
, en prenant le type d'exécution dethis
. Cependant, cela peut provoquer des maux de tête avec les programmes existants, qui appellent des méthodes statiques (apparemment locales) sans décoration (ce qui est sans doute équivalent àthis.method()
).Qu'en est-il des appels sans fioritures
staticMethod()
? Je suggère qu'ils fassent de même qu'aujourd'hui et utilisent le contexte de classe local pour décider quoi faire. Sinon, une grande confusion s'ensuivrait. Bien sûr, cela signifie quemethod()
cela signifieraitthis.method()
simethod
c'était une méthode non statique etThisClass.method()
simethod
c'était une méthode statique. Ceci est une autre source de confusion.Autres considérations
Si nous changions ce comportement (et rendions des appels statiques potentiellement non locaux dynamiques), nous voudrions probablement revoir la signification de
final
,private
et enprotected
tant que qualificatifs sur lesstatic
méthodes d'une classe. Nous devrons alors tous nous habituer au fait que les méthodesprivate static
etpublic final
ne sont pas remplacées et peuvent donc être résolues en toute sécurité au moment de la compilation et sont "sûres" à lire comme références locales.la source
En fait, nous avions tort.
Bien que Java ne vous permette pas de remplacer les méthodes statiques par défaut, si vous examinez attentivement la documentation des classes Class et Method en Java, vous pouvez toujours trouver un moyen d'émuler les méthodes statiques en remplaçant la solution de contournement suivante:
Sortie résultante:
ce que nous essayions de réaliser :)
Même si nous déclarons la troisième variable Carl comme RegularEmployee et lui assignons une instance de SpecialEmployee, nous aurons toujours un appel de la méthode RegularEmployee dans le premier cas et un appel de la méthode SpecialEmployee dans le second cas
il suffit de regarder la console de sortie:
;)
la source
Les méthodes statiques sont traitées comme globales par la JVM, elles ne sont pas du tout liées à une instance d'objet.
Conceptuellement, cela pourrait être possible si vous pouviez appeler des méthodes statiques à partir d'objets de classe (comme dans des langages comme Smalltalk) mais ce n'est pas le cas en Java.
ÉDITER
Vous pouvez surcharger la méthode statique, c'est ok. Mais vous ne pouvez pas remplacer une méthode statique, car les classes ne sont pas des objets de première classe. Vous pouvez utiliser la réflexion pour obtenir la classe d'un objet au moment de l'exécution, mais l'objet que vous obtenez ne correspond pas à la hiérarchie des classes.
Vous pouvez réfléchir sur les classes, mais cela s'arrête là. Vous n'appelez pas une méthode statique en utilisant
clazz1.staticMethod()
, mais en utilisantMyClass.staticMethod()
. Une méthode statique n'est pas liée à un objet et il n'y a donc aucune notion dethis
nisuper
dans une méthode statique. Une méthode statique est une fonction globale; en conséquence, il n'y a pas non plus de notion de polymorphisme et, par conséquent, le dépassement de méthode n'a aucun sens.Mais cela pourrait être possible s'il
MyClass
s'agissait d'un objet au moment de l'exécution sur lequel vous appelez une méthode, comme dans Smalltalk (ou peut-être JRuby comme un commentaire le suggère, mais je ne sais rien de JRuby).Oh ouais ... encore une chose. Vous pouvez invoquer une méthode statique via un objet
obj1.staticMethod()
mais ce sucre vraiment syntaxique pourMyClass.staticMethod()
et doit être évité. Il déclenche généralement un avertissement dans l'IDE moderne. Je ne sais pas pourquoi ils ont autorisé ce raccourci.la source
clazz2 instanceof clazz1
correctement, vous pouvez utiliser à la placeclass2.isAssignableFrom(clazz1)
, ce qui, je crois, retournerait vrai dans votre exemple.La substitution de méthode est rendue possible par la répartition dynamique , ce qui signifie que le type déclaré d'un objet ne détermine pas son comportement, mais plutôt son type d'exécution:
Même si les deux
lassie
etkermit
sont déclarés comme des objets de typeAnimal
, leur comportement (méthode.speak()
) varie car la répartition dynamique ne liera l'appel de méthode.speak()
à une implémentation qu'au moment de l'exécution - pas au moment de la compilation.Maintenant, voici où le
static
mot - clé commence à avoir un sens: le mot "statique" est un antonyme pour "dynamique". Donc, la raison pour laquelle vous ne pouvez pas remplacer les méthodes statiques est qu'il n'y a pas de répartition dynamique sur les membres statiques - parce que statique signifie littéralement "non dynamique". S'ils distribuaient dynamiquement (et pouvaient donc être remplacés), lestatic
mot clé n'aurait tout simplement plus de sens.la source
Oui. Pratiquement Java permet de remplacer la méthode statique, et non théoriquement si vous remplacez une méthode statique en Java, elle se compilera et s'exécutera sans problème, mais elle perdra le polymorphisme qui est la propriété de base de Java. Vous lirez partout qu'il n'est pas possible d'essayer de compiler et d'exécuter vous-même. vous obtiendrez votre réponse. Par exemple, si vous avez Class Animal et une méthode statique, eat () et que vous remplacez cette méthode statique dans sa sous-classe, appelons-la Dog. Ensuite, lorsque vous affectez un objet Chien à une référence animale et que vous appelez eat () selon Java Dog, eat () aurait dû être appelé mais en mode statique Overriding Animals, eat () sera appelé.
Selon le principe de polymorphisme de Java, la sortie devrait être
Dog Eating
.Mais le résultat était différent car pour prendre en charge le polymorphisme, Java utilise la liaison tardive, ce qui signifie que les méthodes ne sont appelées qu'au moment de l'exécution, mais pas dans le cas des méthodes statiques. Dans le compilateur de méthodes statiques, le compilateur appelle des méthodes au moment de la compilation plutôt qu'au moment de l'exécution, nous obtenons donc des méthodes en fonction de la référence et non en fonction de l'objet une référence contenant ce qui explique pourquoi vous pouvez dire Pratiquement, il prend en charge le dépassement statique, mais théoriquement, il ne fonctionne pas 't.
la source
la substitution est réservée aux membres d'instance pour prendre en charge le comportement polymorphe. les membres de classe statiques n'appartiennent pas à une instance particulière. au lieu de cela, les membres statiques appartiennent à la classe et, par conséquent, la substitution n'est pas prise en charge car les sous-classes héritent uniquement des membres d'instance protégés et publics et non des membres statiques. Vous voudrez peut-être définir une usine d'interface et de recherche et / ou des modèles de conception de stratégie pour évaluer une autre approche.
la source
En Java (et dans de nombreux langages OOP, mais je ne peux pas parler pour tous; et certains n'ont pas du tout statique) toutes les méthodes ont une signature fixe - les paramètres et les types. Dans une méthode virtuelle, le premier paramètre est implicite: une référence à l'objet lui-même et lorsqu'il est appelé à partir de l'objet, le compilateur ajoute automatiquement
this
.Il n'y a pas de différence pour les méthodes statiques - elles ont toujours une signature fixe. Cependant, en déclarant la méthode statique, vous avez explicitement déclaré que le compilateur ne doit pas inclure le paramètre d'objet implicite au début de cette signature. Par conséquent, tout autre code qui appelle cela ne doit pas tenter de mettre une référence à un objet sur la pile . Si c'était le cas, l'exécution de la méthode ne fonctionnerait pas car les paramètres seraient au mauvais endroit - décalés d'un - sur la pile.
En raison de cette différence entre les deux; les méthodes virtuelles ont toujours une référence à l'objet contextuel (c'est-à-dire
this
), il est donc possible de référencer tout ce qui, dans le tas, appartient à cette instance de l'objet. Mais avec les méthodes statiques, étant donné qu'aucune référence n'est transmise, cette méthode ne peut accéder à aucune variable et méthode d'objet car le contexte n'est pas connu.Si vous souhaitez que Java modifie la définition afin qu'un contexte d'objet soit transmis pour chaque méthode, statique ou virtuelle, alors vous ne disposerez essentiellement que de méthodes virtuelles.
Comme quelqu'un l'a demandé dans un commentaire à l'op - quelle est la raison et le but de cette fonctionnalité?
Je ne connais pas beaucoup Ruby, comme cela a été mentionné par le PO, j'ai fait quelques recherches. Je vois que dans Ruby, les classes sont vraiment un type spécial d'objet et on peut créer (même dynamiquement) de nouvelles méthodes. Les classes sont des objets de classe complète en Ruby, ils ne sont pas en Java. C'est juste quelque chose que vous devrez accepter lorsque vous travaillerez avec Java (ou C #). Ce ne sont pas des langages dynamiques, bien que C # ajoute certaines formes de dynamique. En réalité, Ruby n'a pas de méthodes "statiques" pour autant que je puisse trouver - dans ce cas, ce sont des méthodes sur l'objet de classe singleton. Vous pouvez ensuite remplacer ce singleton par une nouvelle classe et les méthodes de l'objet de classe précédent appellent celles définies dans la nouvelle classe (correct?). Donc, si vous appelez une méthode dans le contexte de la classe d'origine, elle n'exécutera toujours que la statique d'origine, mais appeler une méthode dans la classe dérivée, appelerait des méthodes à partir du parent ou de la sous-classe. Intéressant et je peux y voir une certaine valeur. Il faut un schéma de pensée différent.
Puisque vous travaillez en Java, vous devrez vous adapter à cette façon de faire. Pourquoi ont-ils fait ça? Eh bien, probablement pour améliorer les performances à l'époque en fonction de la technologie et de la compréhension disponibles. Les langages informatiques sont en constante évolution. Remontez assez loin et il n'y a rien de tel que la POO. À l'avenir, il y aura d'autres nouvelles idées.
EDIT : Un autre commentaire. Maintenant que je vois les différences et en tant que développeur Java / C # moi-même, je peux comprendre pourquoi les réponses que vous obtenez des développeurs Java peuvent prêter à confusion si vous venez d'un langage comme Ruby. Les
static
méthodes Java ne sont pas les mêmes que lesclass
méthodes Ruby . Les développeurs Java auront du mal à comprendre cela, tout comme ceux qui travaillent principalement avec un langage comme Ruby / Smalltalk. Je peux voir comment cela serait également très déroutant par le fait que Java utilise également la "méthode de classe" comme une autre façon de parler des méthodes statiques, mais ce même terme est utilisé différemment par Ruby. Java n'a pas de méthodes de classe de style Ruby (désolé); Ruby ne dispose pas de méthodes statiques de style Java qui ne sont en fait que de vieilles fonctions de style procédural, comme en C.Soit dit en passant - merci pour la question! J'ai appris quelque chose de nouveau pour moi aujourd'hui sur les méthodes de classe (style Ruby).
la source
Eh bien ... la réponse est NON si vous pensez du point de vue du comportement d'une méthode remplacée en Java. Mais, vous n'obtenez aucune erreur du compilateur si vous essayez de remplacer une méthode statique. Cela signifie que si vous essayez de remplacer, Java ne vous empêche pas de le faire; mais vous n'obtiendrez certainement pas le même effet que vous obtenez pour les méthodes non statiques. Le remplacement en Java signifie simplement que la méthode particulière serait appelée en fonction du type d'exécution de l'objet et non du type de compilation de celui-ci (ce qui est le cas avec les méthodes statiques remplacées). D'accord ... des suppositions pour la raison pour laquelle se comportent-ils étrangement? Parce que ce sont des méthodes de classe et que l'accès à celles-ci est toujours résolu pendant la compilation uniquement en utilisant les informations de type de compilation.
Exemple : essayons de voir ce qui se passe si nous essayons de remplacer une méthode statique: -
Sortie : -
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Remarquez la deuxième ligne de la sortie. Si le staticMethod avait été remplacé, cette ligne aurait dû être identique à la troisième ligne car nous invoquons le 'staticMethod ()' sur un objet de type Runtime comme 'SubClass' et non pas comme 'SuperClass'. Cela confirme que les méthodes statiques sont toujours résolues en utilisant uniquement leurs informations de type de temps de compilation.
la source
En général, cela n'a pas de sens de permettre le «remplacement» des méthodes statiques car il n'y aurait pas de bon moyen de déterminer laquelle appeler au moment de l'exécution. Prenons l'exemple de l'employé, si nous appelons RegularEmployee.getBonusMultiplier () - quelle méthode est censée être exécutée?
Dans le cas de Java, on pourrait imaginer une définition de langage où il est possible de "remplacer" les méthodes statiques tant qu'elles sont appelées via une instance d'objet. Cependant, tout ce que cela ferait serait de réimplémenter des méthodes de classe régulières, en ajoutant de la redondance au langage sans vraiment ajouter aucun avantage.
la source
En remplaçant, nous pouvons créer une nature polymorphe en fonction du type d'objet. La méthode statique n'a aucun rapport avec l'objet. Ainsi, java ne peut pas prendre en charge la substitution de méthode statique.
la source
J'aime et double le commentaire de Jay ( https://stackoverflow.com/a/2223803/1517187 ).
Je suis d'accord que c'est la mauvaise conception de Java.
De nombreuses autres langues prennent en charge la substitution des méthodes statiques, comme nous le voyons dans les commentaires précédents. Je pense que Jay est également venu à Java de Delphi comme moi.
Delphi (Object Pascal) a été le premier langage à implémenter la POO.
Il est évident que beaucoup de gens avaient de l'expérience avec cette langue car c'était dans le passé la seule langue pour écrire des produits GUI commerciaux. Et - oui, nous pourrions dans Delphi remplacer les méthodes statiques. En fait, les méthodes statiques dans Delphi sont appelées "méthodes de classe", tandis que Delphi avait le concept différent de "méthodes statiques Delphi" qui étaient des méthodes avec liaison anticipée. Pour outrepasser les méthodes, vous avez dû utiliser une liaison tardive, déclarez la directive "virtuelle". C'était donc très pratique et intuitif et je m'attendrais à cela en Java.
la source
À quoi cela sert-il de remplacer les méthodes statiques? Vous ne pouvez pas appeler de méthodes statiques via une instance.
EDIT: Il semble que par une mauvaise surveillance de la conception du langage, vous pouvez appeler des méthodes statiques via une instance. En général, personne ne fait ça. Ma faute.
la source
variable.staticMethod()
, au lieu deClass.staticMethod()
, oùvariable
est une variable avec un type déclaréClass
. Je suis d'accord que c'est un mauvais langage.La substitution en Java signifie simplement que la méthode particulière serait appelée en fonction du type d'exécution de l'objet et non en fonction de son type au moment de la compilation (ce qui est le cas avec les méthodes statiques substituées). Comme les méthodes statiques sont des méthodes de classe, elles ne sont pas des méthodes d'instance, elles n'ont donc rien à voir avec le fait que la référence pointe vers quel objet ou instance, car en raison de la nature de la méthode statique, elle appartient à une classe spécifique. Vous pouvez la redéclarer dans la sous-classe, mais cette sous-classe ne saura rien des méthodes statiques de la classe parente car, comme je l'ai dit, elle est spécifique uniquement à la classe dans laquelle elle a été déclarée. Les accéder à l'aide de références d'objets n'est qu'une liberté supplémentaire donnée par les concepteurs de Java et nous ne devons certainement pas penser à arrêter cette pratique uniquement lorsqu'ils la restreignent plus de détails et d'exemples. http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
la source
En remplaçant, vous obtenez un polymorphisme dynamique. Lorsque vous dites remplacer les méthodes statiques, les mots que vous essayez d'utiliser sont contradictoires.
Static dit - temps de compilation, le remplacement est utilisé pour le polymorphisme dynamique. Les deux sont de nature opposée et ne peuvent donc pas être utilisés ensemble.
Le comportement polymorphe dynamique survient lorsqu'un programmeur utilise un objet et accède à une méthode d'instance. JRE mappera différentes méthodes d'instance de différentes classes en fonction du type d'objet que vous utilisez.
Lorsque vous dites remplacer les méthodes statiques, les méthodes statiques auxquelles nous accèderons en utilisant le nom de classe, qui sera lié au moment de la compilation, il n'y a donc pas de concept de liaison des méthodes à l'exécution avec des méthodes statiques. Ainsi, le terme «remplacer» les méthodes statiques lui-même n'a aucun sens.
Remarque: même si vous accédez à une méthode de classe avec un objet, le compilateur java est toujours assez intelligent pour le découvrir et fera une liaison statique.
la source
Box.createBox
plus de sens queBoxFactory.createBox
, et est un modèle inévitable lorsqu'il faut vérifier la construction sans lancer d'exceptions (les constructeurs ne peuvent pas échouer, ils ne peuvent que tuer le processus / throw exception), alors qu'une méthode statique peut retourner null en cas d'échec, ou même accepter des rappels de succès / erreur pour écrire quelque chose comme hastebin.com/codajahati.java .La réponse à cette question est simple, la méthode ou la variable marquée comme statique appartient à la classe uniquement, de sorte que cette méthode statique ne peut pas être héritée dans la sous-classe car elle appartient à la super classe uniquement.
la source
Solution simple: utilisez une instance singleton. Il permettra les remplacements et l'héritage.
Dans mon système, j'ai la classe SingletonsRegistry, qui retourne une instance pour la classe passée. Si l'instance n'est pas trouvée, elle est créée.
Cours de langue Haxe:
la source
Singleton.get()
. Le registre est juste une surcharge, et il empêche GC sur les classes.Une méthode statique, une variable, un bloc ou une classe imbriquée appartient à la classe entière plutôt qu'à un objet.
Une méthode en Java est utilisée pour exposer le comportement d'un objet / classe. Ici, comme la méthode est statique (c.-à-d., La méthode statique est utilisée pour représenter le comportement d'une classe uniquement.) Changer / remplacer le comportement de toute la classe violera le phénomène de l'un des piliers fondamentaux de la programmation orientée objet, c'est-à-dire une cohésion élevée . (rappelez-vous qu'un constructeur est un type spécial de méthode en Java.)
Haute cohésion - Une classe ne devrait avoir qu'un seul rôle. Par exemple: une classe de voiture ne devrait produire que des objets de voiture et non des vélos, des camions, des avions, etc. Mais la classe de voiture peut avoir certaines caractéristiques (comportement) qui n'appartiennent qu'à elle-même.
Par conséquent, lors de la conception du langage de programmation Java. Les concepteurs de langage pensaient permettre aux développeurs de garder certains comportements d'une classe pour eux uniquement en rendant une méthode statique dans la nature.
Le code pièce ci-dessous essaie de remplacer la méthode statique, mais ne rencontrera aucune erreur de compilation.
En effet, ici , nous ne surchargez pas une méthode , mais nous sommes juste re-déclarer il. Java permet la re-déclaration d'une méthode (statique / non statique).
La suppression du mot clé statique de la méthode getVehileNumber () de la classe Car entraînera une erreur de compilation. Depuis, nous essayons de modifier la fonctionnalité de la méthode statique qui appartient uniquement à la classe Vehicle.
De plus, si getVehileNumber () est déclaré final, le code ne sera pas compilé, puisque le mot clé final empêche le programmeur de déclarer à nouveau la méthode.
Dans l'ensemble, c'est aux concepteurs de logiciels de savoir où utiliser les méthodes statiques. Personnellement, je préfère utiliser des méthodes statiques pour effectuer certaines actions sans créer d'instance de classe. Deuxièmement, cacher le comportement d'une classe au monde extérieur.
la source
Voici une explication simple. Une méthode statique est associée à une classe tandis qu'une méthode d'instance est associée à un objet particulier. Les remplacements permettent d'appeler les différentes implémentations des méthodes substituées associées à l'objet particulier. Il est donc contre-intuitif de remplacer la méthode statique qui n'est même pas associée aux objets mais à la classe elle-même en premier lieu. Les méthodes statiques ne peuvent donc pas être remplacées en fonction de l'objet qui l'appelle, elles seront toujours associées à la classe où elles ont été créées.
la source
public abstract IBox createBox();
interface IBox interne? Box peut implémenter IBox pour remplacer createBox, et faire en sorte que la création d'objet aboutisse à un IBox valide, sinon retourner un null. Les constructeurs ne peuvent pas retourner "null" et donc vous êtes obligé (1) d'utiliser des exceptions PARTOUT (ce que nous faisons maintenant), ou (2) de créer des classes d'usine qui font ce que j'ai dit plus tôt mais d'une manière qui n'a aucun sens pour les novices ou les experts de Java (ce que nous faisons aussi maintenant). Les méthodes statiques non implémentées résolvent ce problème.Maintenant, en voyant les réponses ci-dessus, tout le monde sait que nous ne pouvons pas remplacer les méthodes statiques, mais il ne faut pas mal comprendre le concept d'accès aux méthodes statiques à partir de la sous-classe .
Par exemple, voir ci-dessous le code: -
Production:-
Merci
la source
Le code suivant montre que c'est possible:
la source
osm
n'estOverridenStaticMeth
pasOverrideStaticMeth
.