103 votes

Remplacer ou masquer Java - Confusion

Je ne comprends pas bien la différence entre l'overriding et le hiding en Java. Quelqu'un peut-il me donner plus de détails sur ces différences ? J'ai lu le Tutoriel Java mais l'exemple de code me laisse encore perplexe.

Pour être plus clair, je comprends bien la notion de surcharge. Mon problème est que je ne vois pas en quoi le masquage est différent, à l'exception du fait que l'un est au niveau de l'instance alors que l'autre est au niveau de la classe.

En regardant le code du tutoriel Java :

public class Animal {
    public static void testClassMethod() {
        System.out.println("Class" + " method in Animal.");
    }
    public void testInstanceMethod() {
        System.out.println("Instance " + " method in Animal.");
    }
}

Ensuite, nous avons une sous-classe Cat :

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The class method" + " in Cat.");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method" + " in Cat.");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

Puis ils disent :

Le résultat de ce programme est le suivant :

Méthode de classe dans Animal.

La méthode d'instance dans Cat.

Pour moi, le fait d'appeler une méthode de classe testClassMethod() directement à partir du Animal exécute la méthode dans Animal La classe est assez évidente, rien de spécial ici. Ensuite, ils appellent la classe testInstanceMethod() à partir d'une référence à myCat Il est donc à nouveau évident que la méthode exécutée est celle de l'instance de Cat .

D'après ce que je vois, le masquage des appels se comporte exactement comme la surcharge, alors pourquoi faire cette distinction ? Si j'exécute ce code en utilisant les classes ci-dessus :

Cat.testClassMethod();

Je vais prendre : La méthode de classe dans Cat. Mais si je retire le testClassMethod() de Cat, alors j'aurai : La méthode de la classe dans Animal.

Ce qui me montre qu'écrire une méthode statique, avec la même signature que dans le parent, dans une sous-classe revient à faire une surcharge.

J'espère que j'ai clarifié mes points de confusion et que quelqu'un pourra m'éclairer. Merci beaucoup par avance !

0 votes

120voto

Kazekage Gaara Points 7978

La surcharge supporte essentiellement la liaison tardive. Par conséquent, c'est au moment de l'exécution que l'on décide quelle méthode sera appelée. C'est le cas pour les méthodes non statiques.

Le masquage concerne tous les autres membres (méthodes statiques, membres d'instance, membres statiques). Il est basé sur la liaison précoce. Plus clairement, la méthode ou le membre à appeler ou à utiliser est décidé lors de la compilation.

Dans votre exemple, le premier appel, Animal.testClassMethod() est un appel à un static il est donc pratiquement sûr de la méthode qui sera appelée.

Au deuxième appel, myAnimal.testInstanceMethod() vous appelez une méthode non statique. C'est ce qu'on appelle le polymorphisme d'exécution. Ce n'est qu'au moment de l'exécution que l'on décide quelle méthode doit être appelée.

Pour plus de précisions, lisez Remplacer ou cacher .

3 votes

Merci pour cette réponse rapide, cela clarifie les choses ! J'ai remarqué que dans l'exemple de JavaRanch, ils ont utilisé la variable pour appeler la méthode de la classe au lieu d'utiliser la classe directement, ce qui rend la chose plus facile à comprendre. Je suppose que dans le tutoriel Java, ils ont utilisé la classe directement parce que l'utilisation d'une instance pour appeler une méthode statique n'est probablement pas une bonne pratique, mais ils auraient dû utiliser monAnimal.testClassMethod() au lieu de Animal.testClassMethod() .

0 votes

+1 pour avoir su le mettre en mots correctement, plutôt que par l'exemple ! :)

0 votes

@Kazekage Gaara Y a-t-il une différence entre surcharger et cacher ?

20voto

Hugo Points 3276

Les méthodes statiques sont cachées, les méthodes non statiques sont surchargées. La différence est notable lorsque les appels ne sont pas qualifiés "quelque chose()" vs "this.quelque chose()".

Je n'arrive pas vraiment à le mettre en mots, alors voici un exemple :

public class Animal {

    public static void something() {
        System.out.println("animal.something");
    }

    public void eat() {
        System.out.println("animal.eat");
    }

    public Animal() {
        // This will always call Animal.something(), since it can't be overriden, because it is static.
        something();
        // This will call the eat() defined in overriding classes.
        eat();
    }

}

public class Dog extends Animal {

    public static void something() {
        // This method merely hides Animal.something(), making it uncallable, but does not override it, or alter calls to it in any way.
        System.out.println("dog.something");
    }

    public void eat() {
        // This method overrides eat(), and will affect calls to eat()
        System.out.println("dog.eat");
    }

    public Dog() {
        super();
    }

    public static void main(String[] args) {
        new Dog();
    }

}

SORTIE :

animal.something
dog.eat

1 votes

Ok, alors que se passerait-il si j'appelle ` chien husky = nouveau chien();' et que j'appelle husky.Animal(); imprimera-t-il animal.quelque chose o chien.quelque chose ? je suppose que c'est C'est FAUX de dire ** que **Ceci appellera toujours Animal.quelque chose()

0 votes

@amarnathharish Tu ne peux pas faire .Animal() Souvenez-vous. Animal() est un constructeur.

0 votes

Et pour clarifier les choses pour ceux qui se posent la question, la raison pour laquelle les something() en Animal() toujours d'appel d'animaux something() est dû au fait que l'appel à une méthode statique est résolu au moment de la compilation plutôt qu'au moment de l'exécution. Cela signifie que l'appel à une méthode statique dans Animal() appelle toujours implicitement Animal.something() . C'est assez intuitif si l'on y réfléchit : l'appel à une méthode statique doit être précédé d'un nom de classe (c.-à-d. className.staticMethodName() ), sauf si l'appel est dans la même classe.

14voto

Rudy Points 2390

C'est la différence entre les surcharges et les masques,

  1. Si les deux méthodes de la classe parent et de la classe enfant sont des méthodes d'instance, elles sont appelées "overrides".
  2. Si les deux méthodes de la classe parent et de la classe enfant sont des méthodes statiques, on parle de dissimulation.
  3. Une méthode ne peut être statique dans le parent et en tant qu'instance dans l'enfant. et vice versa.

enter image description here

3 votes

Vous avez copié et collé ce tableau directement du tutoriel que le PO a dit ne pas avoir compris.

0 votes

Le tableau est très clair : dans les exemples, tous les cas n'ont pas été pris en compte.

3voto

thagorn Points 555

Si je comprends bien votre question, la réponse est "vous êtes déjà en train d'écraser".

"Ce qui me montre que l'écriture d'une méthode statique, avec le même nom que dans le parent, dans une sous-classe fait à peu près une surcharge."

Si vous écrivez une méthode dans une sous-classe avec exactement le même nom qu'une méthode dans une super-classe, elle remplacera la méthode de la super-classe. L'annotation @Override n'est pas nécessaire pour remplacer une méthode. Elle rend cependant votre code plus lisible et oblige le compilateur à vérifier que vous surchargez effectivement une méthode (et que vous n'avez pas mal orthographié la méthode de la sous-classe, par exemple).

1 votes

Cette réponse n'aborde pas la question des méthodes d'instance et des méthodes statiques en ce qui concerne le recouvrement et le masquage.

2voto

abson Points 1716

Veuillez consulter le tutoriel suivant pour obtenir plus d'explications sur cette question : http://www.xyzws.com/Javafaq/can-static-methods-be-overridden/1

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