0

Lorsque j'utilise des classes internes anonymes pour créer des nœuds. Lorsque j'imprime toutes les clés, elles impriment en tant que 0 au lieu des valeurs que j'ai assignées dans la déclaration de classe anonyme. Est-ce que je fais quelque chose de mal? Voici mon code:Les membres de la classe interne anonyme ne sont pas accessibles, en Java

public class LinkedListTest { 
Node head; 

public void addInOrder(final int value) { 
    if (head == null) { 
     head = new Node() { 
      int key = value; 
     }; 
    } 
    else if(head.key > value) { 
     final Node temp = head; 
     head = new Node() { 
      int key = value; 
      Node next = temp; 
     }; 
    } 
    else { 
     Node theNode = head; 
     while(theNode.key < value) { 
      if (theNode.next == null) { 
       theNode.next = new Node() { 
        int key = value; 
       }; 
       return; 
      } 
      else if(theNode.next.key > value) { 
       final Node temp = theNode.next; 
       theNode.next = new Node() { 
        int key = value; 
        Node next = temp; 
       }; 
       return; 
      } 
      theNode = theNode.next; 
     } 
    } 
} 

Et voici ma déclaration de classe pour mon nœud:

class Node { 
    int key; 
    Node next; 
} 

Et voici ma méthode d'impression:

public void printAll(Node hasNode) { 
    if (hasNode != null) { 
     System.out.println(hasNode.key); 
     if (hasNode.next != null) { 
      printAll(hasNode.next); 
     } 
    } 
} 

Répondre

3

Ceci est parce que vous n'êtes pas assignez valeurs dans les champs Node, vous affectez des valeurs aux champs de la sous-classe anonyme avec les mêmes noms.

Ajouter un constructeur à Node et ne créent pas une sous-classe anonyme:

class Node { 
    int key; 
    Node next; 

    Node(int key, Node next) { 
    this.key = key; this.next = next; 
    } 
} 

En option, vous pouvez ajouter un deuxième constructeur qui prend juste la clé:

Node(int key) { 
    this(key, null); 
    } 

L'alternative est il suffit d'appeler new Node(key, null).

+0

Andy m'a battu de quelques secondes :-), mais oui, c'est ce qui se passe. Dans la sous-classe anonyme, 'int key = value;' déclare et initialise une variable d'instance dans la sous-classe anonyme qui remplace le champ du même nom dans 'Node'. – blm

+0

Je comprends, mais quel est le point d'une classe interne anonyme si les champs de valeurs que je leur attribue ne sont pas accessibles en dehors de la portée de leur déclaré? Je pensais que «l'observation» fonctionnerait dans ce cas. Merci également pour vos commentaires! –

+0

Il existe de nombreuses utilisations pour les classes internes anonymes qui n'impliquent pas la déclaration de variables membres du même nom. Cependant, toute variable membre ou méthode non prioritaire déclarée à l'intérieur de la classe interne anonyme est (presque) inaccessible, puisque vous avez simplement une référence à un 'Node', pas' LinkedListTest $ 1', la sous-classe spécifique de 'Node'. –

0

Comme Andy Turner a répondu, vous avez déclaré key et next dans votre classe anonyme comme variables d'instance de la classe anonyme, et vous initialisez ces variables d'instance, mais ils sont sans rapport avec les variables d'instance du même nom de la classe Node .

S'il serait plus facile de comprendre, ceci:

theNode.next = new Node() { 
    int key = value; 
    Node next = temp; 
}; 

est équivalente à une classe locale comme celui-ci:

class Foo extends Node { 
    int key = value; 
    Node next = temp; 
}; 
theNode.next = new Foo(); 

ou vous pouvez même soulever la classe de la méthode afin la capture est plus claire:

// outside the method 
class Foo extends Node { 
    int key; 
    Node next; 
    Foo(int value, Node temp) { key = value; next = temp; } 
}; 
// inside the method 
theNode.next = new Foo(value, temp); 

Le point est, dans tous ces cas, vous attribuez une valeur s aux variables d'instance Foo, et non aux variables d'instance Node.

Il est possible d'effectuer l'initialisation dans la classe anonyme qui vous permet d'affecter aux variables d'instance de Node. Bien que les classes anonymes ne sont pas des constructeurs (ils ne ont pas besoin eux), l'initialisation peut être fait dans l'instance initialiseur:

theNode.next = new Node() { 
    { 
     key = value; 
     next = temp; 
    } 
}; 

Il est souvent écrit dans le style « double initialisation accolade »:

theNode.next = new Node() {{ 
    key = value; 
    next = temp; 
}};