« Programmation Java/Classes internes » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
WikiBayer (discussion | contributions)
m Révocation des modifications de 194.153.88.133 (discussion) vers la dernière version de JackPotte
Balises : Révocation SWViewer [1.3]
Aucun résumé des modifications
Ligne 7 : Ligne 7 :


Une classe interne statique ne peut accéder qu'aux membres statiques de sa classe contenante, représentée par ''ClassExterne'' dans l'exemple suivant :
Une classe interne statique ne peut accéder qu'aux membres statiques de sa classe contenante, représentée par ''ClassExterne'' dans l'exemple suivant :
<source lang="java">
<syntaxhighlight lang="java">
public class ClasseExterne
public class ClasseExterne
{
{
private int compteur = 0;
private int compteur = 0;
private static String nom = "Exemple";
private static String nom = "Exemple";

static class ClasseInterne
static class ClasseInterne
{
{
private int index = 0;
private int index = 0;
public ClasseInterne()
public ClasseInterne()
{
{
System.out.println("Création d'un objet dans "+nom);
System.out.println("Création d'un objet dans "+nom);
// compteur ne peut être accedé
// compteur ne peut être accedé
}
}
}
}
}
}
</syntaxhighlight>
</source>
La compilation du fichier <code>ClasseExterne.java</code> produit deux fichiers compilés :
La compilation du fichier <code>ClasseExterne.java</code> produit deux fichiers compilés :
* <code>ClasseExterne.class</code> contient la classe <code>ClasseExterne</code> uniquement
* <code>ClasseExterne.class</code> contient la classe <code>ClasseExterne</code> uniquement
Ligne 34 : Ligne 34 :


Exemple (Classe non statique globale) :
Exemple (Classe non statique globale) :
<source lang="java">
<syntaxhighlight lang="java">
public class ClasseExterne
public class ClasseExterne
{
{
private int compteur = 0;
private int compteur = 0;


class ClasseInterne
class ClasseInterne
{
{
private int index = 0;
private int index = 0;
public ClasseInterne()
public ClasseInterne()
{
{
compteur++;
compteur++;
}
}
}
}
}
}
</syntaxhighlight>
</source>
Depuis la classe interne, dans le cas où plusieurs variables ou méthodes portent le même nom dans la classe interne et la classe externe, le pointeur <code>this</code> seul désigne l'instance de la classe interne, tandis que le pointeur <code>this</code> précédé du nom de la classe externe désigne l'instance de la classe externe.
Depuis la classe interne, dans le cas où plusieurs variables ou méthodes portent le même nom dans la classe interne et la classe externe, le pointeur <code>this</code> seul désigne l'instance de la classe interne, tandis que le pointeur <code>this</code> précédé du nom de la classe externe désigne l'instance de la classe externe.
<source lang="java">
<syntaxhighlight lang="java">
public class ClasseExterne
public class ClasseExterne
{
{
private int compteur = 10;
private int compteur = 10;


class ClasseInterne
class ClasseInterne
{
{
private int compteur = 0;
private int compteur = 0;
public void count()
public void count()
{
{
this.compteur++; // -> 1
this.compteur++; // -> 1
ClasseExterne.this.compteur--; // -> 9
ClasseExterne.this.compteur--; // -> 9
}
}
}
}
}
}
</syntaxhighlight>
</source>


== Classe anonyme ==
== Classe anonyme ==


Une classe peut être déclarée au moment de l'instanciation de sa classe parente. On parle alors de classe anonyme. Exemple :
Une classe peut être déclarée au moment de l'instanciation de sa classe parente.
On parle alors de classe anonyme.
Exemple :
<source lang="java">
<syntaxhighlight lang="java">
public class ClasseExterne {
public class ClasseExterne
{
Bissextile b = new Bissextile() {
Bissextile b = new Bissextile()
{
public boolean evaluer(annee) {
public boolean evaluer(annee)
if ((annee%4==0 && annee%100!=0) || annee%400==0) {
{
return true;
if ((annee%4==0 && annee%100!=0) || annee%400==0)
} else {
return false;
return true;
else
}
return false;
}
}
};
};
public static void main(String args[]) {
public static void main(String args[])
long an = Long.parseLong(args[0]);
{
if (b.evaluer(an)) {
long an = Long.parseLong(args[0]);
System.out.println("L'année entrée est bissextile");
if (b.evaluer(an))
} else {
System.out.println("L'année entrée n'est pas bissextile");
System.out.println("L'année entrée est bissextile");
else
}
System.out.println("L'année entrée n'est pas bissextile");
}
}
}
}
</syntaxhighlight>
</source>
La classe Bissextile est ici la classe mère d'une classe anonyme. Cette classe sera automatiquement nommée par le compilateur <code>ClasseExterne$1</code>. Il convient d'observer le point-virgule qui suit l'accolade fermante de sa déclaration.
La classe Bissextile est ici la classe mère d'une classe anonyme. Cette classe sera automatiquement nommée par le compilateur <code>ClasseExterne$1</code>. Il convient d'observer le point-virgule qui suit l'accolade fermante de sa déclaration.



Version du 15 avril 2020 à 17:53

Une classe interne est déclarée à l'intérieur d'une autre classe. Elle peut donc accéder aux membres de la classe externe.

Classe interne statique

Une classe interne statique ne peut accéder qu'aux membres statiques de sa classe contenante, représentée par ClassExterne dans l'exemple suivant :

public class ClasseExterne
{
	private int compteur = 0;
	private static String nom = "Exemple";

	static class ClasseInterne
	{
		private int index = 0;
		public ClasseInterne()
		{
			System.out.println("Création d'un objet dans "+nom);
			// compteur ne peut être accedé
		}
	}
}

La compilation du fichier ClasseExterne.java produit deux fichiers compilés :

  • ClasseExterne.class contient la classe ClasseExterne uniquement
  • ClasseExterne$ClasseInterne.class contient la classe ClasseInterne

Classe interne non statique

Une classe interne non statique peut accéder aux membres statiques de la classe ainsi qu'aux membres de l'objet qui l'a créée. En fait, le compilateur crée un membre supplémentaire dans la classe interne référençant l'objet qui l'a créé.

Une telle classe interne peut-être déclarée de manière globale dans l'objet; elle sera accessible par l'ensemble des méthodes de l'objet. Elle peut aussi être déclarée de manière locale à une méthode de l'objet. Elle sera alors accessible depuis cette seule méthode.

Exemple (Classe non statique globale) :

public class ClasseExterne
{
	private int compteur = 0;

	class ClasseInterne
	{
		private int index = 0;
		public ClasseInterne()
		{
			compteur++;
		}
	}
}

Depuis la classe interne, dans le cas où plusieurs variables ou méthodes portent le même nom dans la classe interne et la classe externe, le pointeur this seul désigne l'instance de la classe interne, tandis que le pointeur this précédé du nom de la classe externe désigne l'instance de la classe externe.

public class ClasseExterne
{
	private int compteur = 10;

	class ClasseInterne
	{
		private int compteur = 0;
		public void count()
		{
			this.compteur++; // -> 1
			ClasseExterne.this.compteur--; // -> 9
		}
	}
}

Classe anonyme

Une classe peut être déclarée au moment de l'instanciation de sa classe parente. On parle alors de classe anonyme. Exemple :

public class ClasseExterne
{
	Bissextile b = new Bissextile()
	{
		public boolean evaluer(annee)
		{
			if ((annee%4==0 && annee%100!=0) || annee%400==0) 
				return true;
			else
				return false;
		}
	};
	public static void main(String args[])
	{
		long an = Long.parseLong(args[0]);
		if (b.evaluer(an))
			System.out.println("L'année entrée est bissextile");
		else
			System.out.println("L'année entrée n'est pas bissextile");
	}
}

La classe Bissextile est ici la classe mère d'une classe anonyme. Cette classe sera automatiquement nommée par le compilateur ClasseExterne$1. Il convient d'observer le point-virgule qui suit l'accolade fermante de sa déclaration.

Cette méthode de création de sous-classe peut également s'appliquer aux interfaces. En utilisant la syntaxe suivante, la classe anonyme créée implémente l'interface spécifiée :

new Interface()
{
    ...implémentation des méthodes de l'interface...
}

Remarques :

  • Une classe anonyme est implicitement considérée comme final (et ne peut donc pas être abstract, abstraite).
  • Une classe anonyme ne peut pas contenir de constructeur. Le constructeur appelé est celui qui correspond à l'instruction d'instanciation. Toutefois, elle peut avoir des blocs d'initialisation.
  • Une classe anonyme ne possède pas d'identificateur et ne peut donc être instanciée qu'une seule fois (d'où son nom).