L'accès externe aux membres de la classe à partir de l'intérieur d'un intérieur classe étendant de l'extérieur de la classe elle-même
Dans l'extrait de code montré ci-dessous, un intérieur de classe hérite d'un extérieur de la classe elle-même.
package test;
class TestInnerClass {
private String value;
public TestInnerClass(String value) {
this.value = value;
}
private String getValue() {
return value;
}
public void callShowValue() {
new InnerClass("Another value").showValue();
}
private final class InnerClass extends TestInnerClass {
public InnerClass(String value) {
super(value);
}
public void showValue() {
System.out.println(getValue());
System.out.println(value);
}
}
}
public final class Test {
public static void main(String[] args) {
new TestInnerClass("Initial value").callShowValue();
}
}
La seule instruction à l'intérieur de la main()
méthode (le dernier extrait) affecte la valeur Initial value
pour le domaine privé value
de la TestInnerClass
classe, puis appelle la callShowValue()
méthode.
La callShowValue()
méthode provoque une autre chaîne - Another value
être pour le domaine privé value
de la TestInnerClass
classe avant d'invoquer le showValue()
méthode de InnerClass
l'extension de TestInnerClass
.
En conséquence, les deux instructions suivantes à l'intérieur de la showValue()
méthode,
System.out.println(getValue());
System.out.println(value);
doit afficher,
Une autre valeur
Une autre valeur
Mais ils affichent,
Valeur initiale
La valeur initiale de la
Pourquoi cela se produit?
OriginalL'auteur Tiny | 2013-10-13
Vous devez vous connecter pour publier un commentaire.
La méthode
getValue()
et le champvalue
sont à la foisprivate
. En tant que tels, ils ne sont pas accessibles aux autres classes, y compris les sous-classes, c'est à dire. ils ne sont pas héritées.Dans
InnerClass#showValue()
en raison du fait que ceux-ci sont privés,
getValue()
etvalue
sont se référant à l'extérieur de la classe de membres, qui sont accessibles, parce que vous êtes dans la même classe, c'est à dire. les classes internes peuvent accéder extérieur de la classe privée membres. Ci-dessus, les appels sont équivalentes àEt puisque vous avez défini
value
commevous voir
"Initial value"
être imprimé deux fois. Il n'existe aucun moyen d'accéder à cesprivate
les membres de la sous-classe.Le point est: n'en faites pas des sous-classes les classes internes.
OriginalL'auteur Sotirios Delimanolis
La clé ici est de comprendre comment les classes internes accède aux membres de l'extérieur des classes. Et comment l'accès à ces membres qualifiés en cas de
private
etnon-private
membres. (Remarque: je vais parler de la non-static
intérieure classes ici, la question est sur que seul).Les classes internes magasin de référence pour enfermer exemple:
Un intérieur de classe stocke une référence à l'instance englobante comme un champ. Le champ est nommé comme
this$0
. La enfermant instance est toujours lié à l'intérieure de la classe de l'objet. Lorsque vous créez un objet à l'intérieur de la classe, de l'intérieur de la classe englobante, la valeur de référence dethis$0
reste le même pour tous, maisthis
de référence serait différent.Vous accédez à
this$0
champ à l'aide deOuter.this
syntaxe dans l'intérieur de la classe. Considérons par exemple ce code:Lorsque vous exécutez ce code, vous obtiendrez de sortie comme ceci:
Avis comment 1st et la 3rd références sont les mêmes, tandis que 2ème et 4ème sont différents.
Externe membres de la classe peuvent être consultés dans l'intérieur de la classe à l'aide de
this$0
référence:Lorsque vous accéder aux champs ou à tout autre membre de l'extérieur de la classe de l'intérieur de la classe, l'accès expression est qualifié automatiquement
this$0
. Vous explicitement qualifier l'accès des membres commethis$0
à l'aide deOuterClass.this
de référence. Donc, envisager de champvalue
à l'extérieur de la classe a étépublic
, puis dans leshowValue()
méthode dans votre intérieur de la classe:les 2 premières instructions d'impression sont équivalentes. Ils seraient compilés dans le même octet code:
Vous ne pouvez pas accéder à l'extérieur des membres de la classe explicitement à l'aide de
this
:Si vous décidez d'essayer de qualifier le champ ou une méthode d'accès expression avec
this
dans l'intérieur de la classe, vous obtiendrez une erreur de compilation:Ci-dessus instruction print ne compile pas, parce que
value
n'est pas un champ de l'intérieur de la classe elle-même. C'est un externe champ de la classe.this
se réfère à l'intérieur de la classe, par exemple, pas de l'extérieur.Histoire changements lorsque l'intérieur de la classe s'étend extérieur de la classe:
Lors de votre intérieur de la classe s'étend à l'extérieur de la classe, c'est le moment où les choses commencent à aller bizarre. Parce que dans ce cas, la qualification de terrain ou de la méthode d'accès avec
this
sera valable pour les non-membres privés. Pourprivate
membres, qui ne serait pas valide, commeprivate
membres ne sont pas héréditaires.Dans le cas de l'héritage intérieur de la classe, l'accès direct de l'extérieur les membres de la classe sont qualifiés à la
this
. Cela signifie que, ils auront accès au centre-membres de la classe. Alors explicitement la qualification de l'accès àOuter.this
se réfèrent au champ de l'enfermer à l'instancethis$0
.Considérant
value
champ est déclaré commepublic
:les deux premiers instruction print imprime le
value
champ de l'intérieur de la classe de l'instance, alors que le 3e rapport d'impression imprime lavalue
champ de protection d'instance. Confus?Souviens que j'ai dit, lors de la création de plusieurs instances de l'intérieur de la classe de l'intérieur que l'extérieur de la classe, ils ont même
this$0
de référence.Envisagez-vous de créer un extérieur instance de classe:
puis dans
callShowValue()
méthode, vous créez une instance de l'intérieur de la classe:Maintenant, la sortie de la
showValue()
de la méthode:Vous remarquez que,
this.value
est différente deOuter.this.value
.Que si vous faites
value
champprivate
:Maintenant, quand vous faites de l'extérieur de la classe champ
private
, alors bien sûr vous ne pouvez pas accéder à l'aide dethis.value;
. Donc, le 2e rapport d'impression ne sera pas compilé.Et l'accès direct au domaine, dans ce cas, serait qualifié avec
this$0
cette fois. maintenant, modifiez le champvalue
privé, et de modifier leshowValue()
méthode:C'est là que réside le problème. La première instruction d'impression qualifie
value
avecthis
outhis$0
si le champ estpublic
ouprivate
.Venir à votre problème concret:
Maintenant dans votre code, puisque les deux
value
champ etgetValue()
méthode estprivate
, leshowValue()
méthode:est la même que:
qui accède au champ et la méthode de l'enfermer instance. Et le champ est encore Valeur Initiale. Et c'est pourquoi la sortie est:
haha 🙂 bien sûr.
OriginalL'auteur Rohit Jain
Dans le cas ci-dessus il y a 2 différentes relations entre TestInnerClass et InnerClass.
Mais il y a un petit twist dans l'histoire..
il y a deux objets! et le problème, c'est que nous mettons "une Autre Valeur" en objet différent! et l'impression de la valeur de l'ancien..
Premier Objet:
Méthode ci-dessus dans la Classe de Test crée une instance de TestInnerClass avec "valeur Initiale"
deuxième Objet:
Depuis le InnerClass est l'extension de la TestInnerClass une autre nouvelle Instance de TestInnerClass est créé avec "une Autre Valeur".
Mais nous avons l'impression de la valeur à partir de vieux objets qui ne sont pas la seconde.
OriginalL'auteur Nakul Patekar
Les autres réponses ont bien expliqué pourquoi vous obtenez les résultats que vous voyez (vous avez deux instances de
TestInnerClass
et accédez à la première), mais il est en fait un chemin pour accéder aux membres privés deTestInnerClass
dans sa sous - classe- le mot-clésuper
.Si vous remplacez votre
showValue
méthode:Vous obtiendrez le résultat que vous attendiez.
Je dirais aussi que si vous décidez de le faire vous faire
InnerClass
une statique à l'intérieur de la classe car il n'est plus besoin d'une référence à une instance de l'extérieur de la classe.OriginalL'auteur Alex