39 votes

Si les méthodes statiques ne peuvent pas être surchargées, comment cela fonctionne-t-il ici (pour Java) ?

J'avais compris que les variables statiques et les méthodes statiques appartiennent à une classe, et non aux objets de la classe. Ainsi, une Override d'une méthode statique ne fonctionnera pas en Java, car pour remplacer une méthode statique, il faut créer une instance d'une classe. Mais j'ai essayé quelque chose aujourd'hui qui contredisait mes connaissances de Java.

Veuillez suivre ce code :

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{    
   public static void doIt(){
      System.out.println("In static method 'doit' of class Child ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

La sortie de l'implémentation ci-dessus est :

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Child

À partir de ce résultat, je peux comprendre que, bien que le Child étend la classe Parent la classe doit Les méthodes sont individuelles à chaque classe car elles sont static . Il n'est donc pas possible de les remplacer.

Maintenant, veuillez suivre le code ci-dessous, où @Override est ajouté à l'image de l'enfant doIt méthode :

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{    
   @Override // Adding this annotation here
   public static void doIt(){
      System.out.println("In static method 'doit' of class Child ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

La sortie du code ci-dessus donne une erreur de compilation comme suit :

D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:31: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

Ici, il est clairement dit que l'annotation Override ne peut pas être appliqué dans static car elles ne sont pas remplacées.

Maintenant, veuillez suivre le code ci-dessous, où Child n'a pas doIt méthode :

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{ /* no doIt method */ }

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

La sortie est :

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Parent

Pourquoi le code ci-dessus compile-t-il et s'exécute-t-il ? Je m'attendais à une erreur de compilation pour la méthode doit pour la classe Child, et je m'attendais à "Method not found". Je ne comprends pas.

Veuillez également suivre le code ci-dessous. Ici, le doIt méthode dans Parent est maintenant final .

class Parent{
   public static final void doIt(){ // now final
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

Le résultat après l'exécution du code ci-dessus est le suivant :

D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:30: error: doIt() in Child cannot override doIt() in Parent
    public static void doIt(){
                       ^
  overridden method is static,final
 1 error

 D:\Rahul Shivsharan\MyPractise\JAVA>

Ce à quoi je m'attendais, c'est que le code ci-dessus fonctionne parfaitement comme le code d'accès à l'Internet. doit sont statiques dans chaque classe, de sorte que même une classe final ne devrait pas provoquer d'erreur de compilation car la méthode est static .

Veuillez m'expliquer comment le remplacement des méthodes fonctionne dans les classes statiques en Java.

  1. Les méthodes statiques peuvent-elles être surchargées ? Si oui, alors comment se fait-il que l'annotation @Override échoue ?
  2. Si les méthodes statiques ne peuvent pas être surchargées, alors comment se fait-il que mon troisième bloc de code fonctionne bien ?
  3. Si les méthodes statiques ne peuvent pas être surchargées, alors comment se fait-il que l'option final mot-clé fait une différence ?

3 votes

Question du jour bien écrite jusqu'à présent :)

41voto

lschuetze Points 465

Tout d'abord, différents mécanismes sont en jeu : Remplacement et ombrage (également appelé dissimulation) .

1) Les méthodes statiques ne peuvent pas être remplacées car elles sont attachées à la classe dans laquelle elles sont définies. Cependant, vous pouvez ombre/masque une méthode statique comme vous le faites avec votre Parent / Child classe. Cela signifie que la méthode est remplacée dans la classe Child mais est toujours disponible auprès de la Parent classe.

Il est de plus en plus évident que vous êtes pas lorsque vous appelez les méthodes statiques à partir d'instances de ces classes (et que vous n'utilisez pas l'option de remplacement). Class.staticMethod() invocation).

Parent parent = new Parent();
Child child1 = new Child();
Parent child2 = new Child();

parent.StaticMethod();
child1.StaticMethod();
child2.StaticMethod();

le résultat est

Static method from Parent
Static method from Child
Static method from Parent

La réponse est la répartition des méthodes. Vous pouvez saisir le code source ici

2) Le dispatch trouve la méthode sur le Parent classe. Il n'y a pas de répartition dynamique, car le type d'exécution est utilisé pour trouver le gestionnaire de méthode. Il utilise le type du temps de compilation. Rappeler : L'appel de méthodes statiques à partir d'instances est considéré comme une mauvaise pratique car des choses comme celles mentionnées ci-dessus peuvent se produire et sont faciles à négliger.

3) Avec final vous déclarez que la méthode ne peut être ni surchargée ni masquée.

3 votes

Il convient en outre de noter que le compilateur ajoute à la confusion avec son message de overridden method is static,final . Il aurait fallu lire shadowed/hidden à la place.

6voto

Jordi Castilla Points 8038

Vous confondez Remplacement de con cacher

10 votes

Ça me fait peur que "déroutant" soit aussi mis en avant. :/

0 votes

@EralpB, je suis d'accord... à la demande générale, un lien vers la section principale de JLS qui contient les informations suivantes déroutant a été effacé :D

4voto

Sweeper Points 1267

Bien qu'il soit déconseillé de poser trois questions dans un même message, je suis tout de même disposé à y répondre.

  1. Les méthodes statiques ne peuvent pas être surchargées parce qu'il n'y a aucun intérêt à le faire. Dans votre cas, si vous voulez surcharger la méthode statique, vous pouvez simplement appeler la méthode et ajouter votre propre implémentation après cela ou vous pouvez simplement créer une autre méthode.

  2. Maintenant que vous savez que les méthodes statiques ne peuvent pas être surchargées. Mais vous vous demandez pourquoi le troisième code fonctionne ? Le troisième code est le code avec

    public class Child extends Parent {}

n'est-ce pas ? Bien que les méthodes statiques ne puissent pas être surchargées, elles peuvent être hérité de . Ce que vous faites, c'est hériter Parent donc c'est tout à fait normal !

  1. Laissez-moi vous dire que dans votre premier exemple de code, vous êtes cacher la méthode dans le Parent et non pas en surchargeant la classe. C'est pourquoi vous obtenez le résultat. A final Le mot-clé signifie que la méthode peut nunca être modifié, ni même caché. C'est pour ça.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X