39 votes

Observation variable en Java

J'ai des doutes sur ce code Java. Le résultat obtenu est "bry velu". Mes questions:

  1. Pourquoi ai-je cette sortie?
  2. Comment puis-je accéder à la référence d'objet String "name" dans la classe ZooKeeper?
  3. Si cela a quelque chose à voir avec l'observation variable, alors quelle variable est observée?

Code:

 class Mammal {
   String name = "furry ";
   String makeNoise() { return "generic noise"; }
 }
 class Zebra extends Mammal {
   String name = "stripes ";
   String makeNoise() { return "bray"; }
 }
 public class ZooKeeper {
   public static void main(String[] args) { new ZooKeeper().go(); }
   void go() {
     Mammal m = new Zebra();
     System.out.println(m.name + m.makeNoise());
     //Output comes as "furry bray". Please explain this.
     //And how can we access the name variable, the one having "stripes " in it.
     //Does it have something to do with Variable Shadowing?
   }
 }
 

63voto

Jon Skeet Points 692016

Les Variables ne sont pas polymorphes. Lorsque vous accédez m.name, qui va toujours utiliser l' Mammal.name champ qui fait partie de l'objet, quel que soit le temps d'exécution type de l'objet. Si vous avez besoin pour obtenir l'accès à l' Zebra.name, vous avez besoin d'une expression à un moment de la compilation type d' Zebra.

L' makeNoise méthode est appelée pratiquement, toutefois, que la mise en œuvre utilisé au moment de l'exécution ne dépend du type de l'objet.

Notez que si vous faites tous vos domaines privés - qui est généralement une bonne idée de toute façon - ce n'est pas un problème.

C'est en fait la clandestinité plutôt que des ombres. Voir JLS la section 8.3 pour plus de détails sur la clandestinité, et la section 6.4.1 pour l'ombrage. Je ne peux pas dire que j'ai toujours garder les différences droite...

15voto

Vishal K Points 9232

Sortie vient comme "furry bray". Veuillez l'expliquer.

fields dans les programmes java ne sont pas accessibles via la recherche dynamique. Au lieu de cela, ils sont résolus de manière statique tout moment de la compilation. C'est pourquoi vous obtenez furry pour m.name. Alors que, methods dans les programmes java sont accessibles via de recherche dynamique. C'est pourquoi vous obtenez bray pour m.makeNoise().

Et comment peut-on accéder à la variable de nom, celui d'avoir des "bandes" dans il?

Et si vous souhaitez accéder Zebra.name , vous devriez type cast m de 'Zebra'.Cela devrait ressembler à ceci:

System.out.println(((Zebra)m).name + m.makeNoise());

Mise à JOUR
Les phénomènes que présente ici est le résultat de Champs Cacher plutôt que de variable d'ombrage.

9voto

blondeamon Points 264

Il n'y a pas de variable de substitution en Java. Vous avez déclaré le nom à la fois dans le parent et dans l'enfant, mais vous y avez fait référence par le biais d'une variable de référence parent. C'est pour ça que tu es 'furry'.

Il y a un dépassement pour les méthodes, c'est pourquoi vous avez eu bray. Parce que lors de l'exécution, il a examiné l'objet réel dans le tas et a vu qu'il s'agissait d'un zèbre.

4voto

Stijn Geukens Points 5482

Les noms de variables en Java sont résolus par le type de référence et non par l'objet auquel ils font référence. Ainsi, m.name fait référence au nom de variable dans Mammal même si la pâte m est un zèbre.

3voto

Ondrej Bozek Points 1988

C'est arrivé parce que votre champ name de Mammal est simplement masqué par name champ de Zebra . Vous pouvez ensuite y accéder simplement en définissant le type requis.
De l'autre côté, la méthode makeNoise() substitue la même méthode à celle du parent afin que vous ne puissiez plus accéder à l'implémentation à partir du parent.

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