2015-10-08 1 views
2

Ma question, en termes abstraits, est:Comment accéder à l'instance d'une classe englobante?

Comment une classe interne non statique peut-elle accéder à l'instance de la classe englobante? Cela est nécessaire pour utiliser l'instance en tant que paramètre dans les appels de méthode et accéder aux méthodes et aux variables avec des noms identiques entre la classe interne et la classe englobante.

Comme les mots-clés this et super vous permettent d'accéder à des versions spécifiques des méthodes et des variables avec des noms identiques dans la classe et les parents, sont là des mots clés pour accéder aux versions de méthodes et variables renfermant des classes et des classes fermées?

Si vous êtes confus, poursuivez votre lecture:

Prenons l'exemple de code suivant, avec deux classes et une classe interne. Main et Outer sont deux classes dans le paquet "myPackage" (sur une note de côté, je ne pouvais pas obtenir le code suivant pour fonctionner sans un paquet/dans le paquet par défaut, pour des raisons inconnues). Inner est une classe interne et non statique d'Outer.

package myPackage; 

public class Outer { 
    public void activate() { 
     System.out.println("Outer.activate"); 
    } 

    public class Inner { 
     public void go() { 
      activate(); 
     } 
    } 
} 

package myPackage; 

import myPackage.Outer.Inner; 

public class Main { 

    public static void main(String[] args) { 
     Outer myOuter = new Outer(); 
     Inner myInner = myOuter.new Inner(); 
     myInner.go(); 
    } 
} 

Notez que je construis un Inner avec myOuter.new Inner(). Comme Inner n'est pas statique, il doit être construit au-dessus d'une instance existante de sa classe englobante: dans ce cas, myOuter. Par conséquent, lorsque j'appelle myInner.go(), myInner appelle activate(), qui appelle activate() sur son instance liée de la classe englobante. Alors myInner appelle myOuter.activate(), et la sortie est:

Outer.activate


Maintenant, tenez compte des modifications suivantes:

package myPackage; 

public class Outer { 
    public void activate() { 
     System.out.println("Outer.activate"); 
    } 

    public class Inner { 
     public void activate() { 
      System.out.println("Inner.activate"); 
      activate(); 
     } 
    } 
} 

package myPackage; 

import myPackage.Outer.Inner; 

public class Main { 

    public static void main(String[] args) { 
     Outer myOuter = new Outer(); 
     Inner myInner = myOuter.new Inner(); 
     myInner.activate(); 
    } 
} 

maintenant WHE n J'appelle myInner.activate(), myInner sorties, puis appelle activate(). Cependant, puisque Inner a maintenant une méthode appelée activate(), myInner utilise cette version au lieu de la version dans l'instance de la classe englobante. Alors myInner appelle myInner.activate(), et la sortie est:

Inner.activate

Inner.activate

Inner.activate

Inner.activate

Inner.activate

Inner.activate

...

De plus en plus, et se termine par une erreur de débordement de pile. Donc, ma question dans ce contexte est de savoir comment changer Inner.activate() de sorte qu'il sort, puis appelle sa version de l'instance englobante de activate() au lieu de la sienne. La sortie serait alors:

Inner.activate

Outer.activate

Merci d'avance pour votre aide.

Répondre

3

Vous accédez this de la classe externe en pré-attente le nom de la classe à this mot-clé, comme suit:

Outer.this.activate(); 

Cela résout le champ d'this pour faire référence à l'objet de la classe externe, qui est implicitement stocké dans des objets de classes internes non statiques.

Demo.

+0

Parfait. Précisément ce dont j'avais besoin. – snickers10m