Beaucoup de gens ne sont peut-être pas familiers avec les classes internes Java. En fait, un concept similaire existe en C++, c'est-à-dire les classes imbriquées. Les différences et les connexions entre les deux seront comparées ci-dessous. En apparence, une classe interne n'est qu'une autre classe définie au sein de la classe (comme vous le verrez ci-dessous, les classes internes peuvent être définies à de nombreux endroits), mais en fait, ce n'est pas si simple à première vue, les classes internes semblent un peu. redondant. L'utilité n'est peut-être pas si évidente pour les débutants, mais avec une compréhension plus approfondie, vous constaterez que les concepteurs de Java ont de bonnes intentions dans les classes internes. Apprendre à utiliser les classes internes fait partie de la maîtrise de la programmation Java avancée, qui vous permet de concevoir la structure de votre programme avec plus d'élégance. Présentons-le sous les aspects suivants :
première réunion
Copiez le code comme suit :
Contenu de l'interface publique {
valeur int();
}
interface publique Destination {
Chaîne readLabel();
}
Biens de classe publique {
classe privée Content implémente Contents {
int privé je = 11 ;
valeur int publique() {
je reviens;
}
}
la classe protégée GDestination implémente Destination {
étiquette de chaîne privée ;
GDestination privée (String où aller) {
étiquette = oùVers ;
}
chaîne publique readLabel() {
étiquette de retour ;
}
}
destination publique dest(String s) {
renvoyer de nouvelles GDestinations ;
}
contenu public cont() {
renvoyer un nouveau contenu ();
}
}
classe TestGoods {
public static void main (String[] arguments) {
Marchandises p = nouvelles marchandises ();
Contenu c = p.cont();
Destination d = p.dest("Pékin");
}
}
Dans cet exemple, les classes Content et GDestination sont définies à l'intérieur de la classe Goods et ont respectivement des modificateurs protected et private pour contrôler les niveaux d'accès. Le contenu représente le contenu des marchandises et GDestination représente la destination des marchandises. Ils implémentent respectivement deux interfaces Contenu et Destination. Dans la méthode principale suivante, vous utilisez directement Contents c et Destination d pour opérer. Vous ne voyez même pas les noms de ces deux classes internes ! De cette façon, le premier avantage des classes internes est de masquer les opérations que vous ne voulez pas que les autres connaissent, c'est-à-dire l'encapsulation.
Dans le même temps, nous avons également découvert la première façon d'obtenir un objet de classe interne en dehors de la portée de la classe externe, qui consiste à le créer et à le renvoyer en utilisant les méthodes de sa classe externe. Les méthodes cont() et dest() de l’exemple ci-dessus font cela. Alors y a-t-il un autre moyen ?
Bien sûr,
le format de syntaxe est le suivant :
externalObject=new externalClass (Paramètres du constructeur);
externalClass.innerClass innerObject=outerObject.new InnerClass (paramètres du constructeur);
Notez que lors de la création d’un objet de classe interne non statique, vous devez d’abord créer l’objet de classe externe correspondant. Quant à la raison, cela nous amène à notre sujet suivant. Les objets de classe interne non statiques ont des références à leurs objets de classe externe.
Modifiez légèrement l'exemple précédent :
Copiez le code comme suit :
Biens de classe publique {
valeur int privéeTaux = 2 ;
classe privée Content implémente Contents {
private int i = 11 * valueRate ;
valeur int publique() {
je reviens;
}
}
la classe protégée GDestination implémente Destination {
étiquette de chaîne privée ;
GDestination privée (String où aller) {
étiquette = oùVers ;
}
chaîne publique readLabel() {
étiquette de retour ;
}
}
destination publique dest(String s) {
renvoyer de nouvelles GDestinations ;
}
contenu public cont() {
renvoyer un nouveau contenu ();
}
}
Ici, nous ajoutons une variable membre privée valueRate à la classe Goods, ce qui signifie que le coefficient de valeur des marchandises est multiplié par celui-ci lorsque la méthode value() de la classe interne Content calcule la valeur. Nous avons constaté que value() peut accéder à valueRate, ce qui est le deuxième avantage des classes internes. Un objet de classe interne peut accéder au contenu de l'objet de classe externe qui l'a créé, même aux variables privées ! Il s'agit d'une fonctionnalité très utile qui nous fournit plus d'idées et de raccourcis lors de la conception. Pour réaliser cette fonction, l'objet de classe interne doit avoir une référence à l'objet de classe externe. Lorsque le compilateur Java crée un objet de classe interne, il transmet implicitement la référence à son objet de classe externe et la conserve. Cela permet à l'objet de classe interne de toujours accéder à son objet de classe externe, et c'est aussi pourquoi pour créer un objet de classe interne en dehors de la portée de la classe externe, vous devez d'abord créer son objet de classe externe.
Certaines personnes peuvent se demander : que dois-je faire si une variable membre de la classe interne a le même nom qu'une variable membre de la classe externe, c'est-à-dire que la variable membre de la classe externe portant le même nom est bloquée ? Ce n'est pas grave. Java utilise le format suivant pour exprimer les références aux classes externes :
classeextérieure.this
Avec lui, nous n'avons pas peur de cette situation de blindage.
classe interne statique
Comme les classes ordinaires, les classes internes peuvent également être statiques. Cependant, par rapport aux classes internes non statiques, la différence est que les classes internes statiques n'ont pas de références externes. Ceci est en fait très similaire aux classes imbriquées en C++. La plus grande différence entre les classes internes Java et les classes imbriquées C++ est de savoir s'il existe des références à l'extérieur. Bien sûr, du point de vue de la conception et de certains de ses détails, il y a une différence.
De plus, dans toute classe interne non statique, il ne peut pas y avoir de données statiques, de méthodes statiques ou d'une autre classe interne statique (les classes internes peuvent être imbriquées sur plusieurs niveaux). Mais vous pouvez avoir tout cela dans des classes internes statiques. Cela peut être considéré comme la deuxième différence entre les deux.
classe interne locale
Oui, les classes internes Java peuvent également être locales, elles peuvent être définies dans une méthode ou même dans un bloc de code.
Copiez le code comme suit :
biens de classe publique1 {
destination publique dest(String s) {
la classe GDestination implémente Destination {
étiquette de chaîne privée ;
GDestination privée (String où aller) {
étiquette = oùVers ;
}
chaîne publique readLabel() {
étiquette de retour ;
}
}
renvoyer de nouvelles GDestinations ;
}
public static void main (String[] arguments) {
Biens1 g = nouveau Biens1();
Destination d = g.dest("Pékin");
}
}
Ce qui précède en est un exemple. Dans la méthode dest, nous définissons une classe interne, et enfin cette méthode renvoie l'objet de cette classe interne. Si nous avons seulement besoin de créer un objet d'une classe interne et de le créer vers l'extérieur, nous pouvons le faire. Bien entendu, les classes internes définies dans les méthodes peuvent diversifier la conception, et leurs utilisations ne se limitent pas à cela.
Voici un exemple encore plus étrange :
Copiez le code comme suit :
biens de classe publique2 {
private void internalTracking(booléen b) {
si (b) {
classe Trackingslip {
identifiant de chaîne privé ;
TrackingSlip(Chaîne s) {
identifiant = s ;
}
Chaîne getslip() {
renvoyer l'identifiant ;
}
}
Trackingslip ts = new Trackingslip("slip");
Chaîne s = ts.getslip();
}
}
piste vide publique() {
internalTracking(true);
}
public static void main (String[] arguments) {
Biens2 g = nouveau Biens2();
g.track();
}
}
Vous ne pouvez pas créer un objet de cette classe interne en dehors du if, car il dépasse sa portée. Cependant, lors de la compilation, la classe interne Trackingslip est compilée en même temps que les autres classes, sauf qu'elle a sa propre portée et n'est pas valide au-delà de cette portée. À part cela, elle n'est pas différente des autres classes internes.
classe interne anonyme
Les règles de syntaxe des classes internes anonymes de Java peuvent sembler un peu étranges, mais comme pour les tableaux anonymes, lorsque vous avez uniquement besoin de créer un objet d'une classe et que vous n'avez pas besoin de son nom, l'utilisation de classes internes peut rendre le code concis et clair. Ses règles de syntaxe sont les suivantes :
nouveau nom d'interface(){......}; ou nouveau nom de superclasse(){......} ;
Continuons avec l'exemple ci-dessous :
Copiez le code comme suit :
biens de classe publique3 {
contenu public cont() {
renvoyer un nouveau contenu() {
int privé je = 11 ;
valeur int publique() {
je reviens;
}
} ;
}
}
La méthode cont() utilise ici une classe interne anonyme pour renvoyer directement un objet d'une classe qui implémente l'interface Contents, ce qui semble en effet très simple.
Dans les adaptateurs anonymes pour le traitement des événements Java, les classes internes anonymes sont largement utilisées. Par exemple, lorsque vous souhaitez fermer la fenêtre, ajoutez ce code :
Copiez le code comme suit :
frame.addWindowListener(nouveau WindowAdapter(){
public void windowClosing(WindowEvent e){
Système.exit(0);
}
});
Une chose à noter est que puisque la classe interne anonyme n'a pas de nom, elle n'a pas de constructeur (mais si la classe interne anonyme hérite d'une classe parent qui ne contient qu'un constructeur paramétré, elle doit apporter ces paramètres lors de sa création, et utiliser le super mot-clé pour appeler le contenu correspondant lors du processus d’implémentation). Si vous souhaitez initialiser ses variables membres, il existe plusieurs méthodes :
S'il s'agit d'une classe interne anonyme d'une méthode, vous pouvez utiliser cette méthode pour transmettre les paramètres souhaités, mais rappelez-vous que ces paramètres doivent être déclarés finaux.
Transformez la classe interne anonyme en une classe interne locale nommée afin qu'elle puisse avoir un constructeur.
Utilisez un bloc d'initialisation dans cette classe interne anonyme.
Pourquoi avez-vous besoin de classes internes ?
Quels sont les avantages des classes internes Java ? Pourquoi avez-vous besoin de classes internes ?
Tout d'abord, prenons un exemple simple. Si vous souhaitez implémenter une interface, mais qu'une méthode de cette interface a le même nom et les mêmes paramètres qu'une méthode de la classe que vous avez conçue, que devez-vous faire ? À ce stade, vous pouvez créer une classe interne pour implémenter cette interface. Étant donné que la classe interne est accessible à tout ce qui se trouve dans la classe externe, cela permettra d'accomplir toutes les fonctionnalités que vous auriez si vous implémentiez directement l'interface.
Mais vous voudrez peut-être vous demander : ne suffirait-il pas de simplement changer de méthode ?
En effet, utiliser cela comme raison pour concevoir des classes internes n’est vraiment pas convaincant.
La vraie raison est la suivante : ensemble, les classes et interfaces internes de Java peuvent résoudre un problème dont les programmeurs C++ se plaignent souvent en Java sans héritage multiple. En fait, l'héritage multiple de C++ est très compliqué à concevoir, et Java peut très bien obtenir l'effet de l'héritage multiple grâce aux classes et interfaces internes.