:: Enseignements :: Master :: M1 :: 2007-2008 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Quelques notes pour le TD3 |
Interface
Une interface définit un type sans code. On utlise le
mot-clé
interface
. Une interface déclare des méthodes sans indiquer le code
(implantation) de celles-ci; on dit alors que les méthodes
sont abstraites. Il n'est pas possible d'instantier une
interface car celle-ci ne définit pas le code de ses
méthodes.
Implanter une Interface
Implanter une interface consiste à déclarer un classe qui
fournira le code pour l'ensemble des méthodes abstraites, on
utilise le mot-clé
implements
. Le compilateur vérifie que toutes les méthodes de
l'interface sont implantées par la classe.
Les méthodes déclarées dans une interface sont
obligatoirement abstraite (
abstract
) et publique (
public
). Les champs déclarés dans une intreface sont
obligatoirement constant (
final
), publique (
public
) et statique (
static
).
Classe abstraite
Il est possible de définir en Java des classes ayant des
méthodes abstraites! Une classe abstraite est une classe
partiellement implantée donc non instantiable. Une classe
abstraite peut s'intercaler dans l'arbre d'héritage entre
l'interface et les classes concrètes.
L'intérêt des classes abstraites est de permettre de
partager du code commun à des sous-classes. Le code commun
peut supposer la présence de certaines méthodes (donc
abstraites).
Classe interne
Il existe quatre types de classe interne:
-
les classes internes simples (
inner class
), définies au niveau des classes,
- les classes internes statiques,
-
les classes locales (ou dites de méthode), définies
au niveau des méthodes,
-
les classes internes anonymes, définies au niveau
d'une instance.
Les classes internes simples sont définies au sein des
classes. Elles constituent des membres à part entière des
classes d'inclusions au même titre que des variables ou des
méthodes.
class ClasseParente {
...
modificateur class ClasseInterne {
// instructions...
}
...
}
Une classe interne peut être déclarée avec n'importe lequel
des modificateurs d'accès et les modificateurs spéciaux
abstract
,
final
ou
static
. Les classes possèdant le modificateur
static
deviennent des classes internes statiques.
Les classes internes ne doivent pas déclarer de membres
statiques, hormis s'ils comportent le modificateur
final
, dans le cas contraire, une erreur de compilation se
produit.
Toutefois, les membres statiques de la classe externe
peuvent être hérités sans problème par la classe interne.
Les classes imbriquées sont capables d'accéder à toutes les
variables et méthodes de la classe parente, y compris celles
déclarées avec un modificateur
private
.
Cette notation particulière spécifie que l'objet créé est
une instance de la classe interne associée à l'objet
résultant de l'instanciation d'une classe de plus haut
niveau.
L'instanciation de la classe interne passe obligatoirement
par une instance préalable de la classe d'inclusion. La
classe parente est d'abord instanciée, puis c'est au tour de
la classe interne de l'être par l'intermédiaire de l'objet
résultant de la première instance.
ClassParente obj_out = new ClasseParente();
ClasseInterne obj_in = obj_out.new ClasseInterne();
// est équivalent à
ClasseInterne obj_in = (new ClassParente()).new ClasseInterne();
La référence d'objet
this
désigne une instance de la classe parente.
Le mot-clé
this
permet d'accéder à un membre de la classe en cours,
c'est-pourquoi
this.variable
accède au membre de la classe interne et
ClasseParente.this.variable
à celui de la classe parente spécifiée.
Les classes internes statiques peuvent accéder à l'ensemble
des membres statiques de leur classe parente, à l'instar des
méthodes de classe. Il n'est pas nécessaire de créer une
instance de la classe parente pour pouvoir instancier la
classe intérieure statique contrairement aux classes
internes simples. Il est possible de créer une instance
d'une classe interne par l'instruction suivante :
new ClasseParente.ClasseInterne()
Les méthodes d'une classe interne statique peuvent être
accédées dans la classe parente de la même façon que les
classes internes simples, c'est-à-dire, suite à
l'instanciation de leur propre classe.
Une classe locale (ou de méthode) est définie à l'intérieur
d'une méthode, et agît librement et essentiellement au sein
de cette dernière.
modificateur class UneClasse {
modificateur type_retour uneMethode([Liste de paramètres]){
class UneClasseLocale {
// instructions...
}
}
}
Les données membres d'une classe externe peuvent être
accédés par la classe locale.
class ClasseExterne {
int x = 10;
int y = 12;
int z = x + y;
void addition(){
class ClasseLocale {
boolean verification(){
if(x + y == z)
return true;
else
return false;
}
}
ClasseLocale obj_in = new ClasseLocale();
if(obj_in.verification()){
x = x + y;
System.out.println("La classe interne a bien accédé aux "
+ "membres de la classe extérieure.n"
+ "x = " + x + "ny = " + y + "nz = " + z);
}
else
System.out.println("Erreur !");
}
}
public static void main(String[] args){
ClasseExterne obj_out = new ClasseExterne();
obj_out.addition();
}
}
Seules les variables locales et les paramètres de la méthode
d'inclusion, déclarées avec le modificateur final, peuvent
être exploitées par les classes internes locales, sinon une
erreur se produit lors de la compilation. De plus, ces
variables doivent être impérativement assignées avant leur
emploi dans la classe locale.
class ClasseExterne {
int x = 10;
int y = 12;
// Paramètre constant utilisable par la classe locale
ClasseExterne(final int p){
// Constante utilisable par la classe locale
final int a = 20;
// Variable inutilisable par la classe locale
int b = 44;
class ClasseLocale {
boolean verification(){
if(x + y == a + p)
return true;
else
return false;
}
}
ClasseLocale obj_in = new ClasseLocale();
if(obj_in.verification()){
x = x + y;
System.out.println("La classe interne a bien accédé aux "
+ "membres de la classe extérieure.n"
+ "x = " + x + "ny = " + y + "na = " + a);
}
else
System.out.println("Erreur !");
}
public static void main(String[] args){
ClasseExterne obj_out = new ClasseExterne(2);
}
}
Les classes anonymes (
anonymous classes
) sont déclarées immédiatement après l'expression
d'instanciation d'une classe, permettant directement
d'étendre ou d'implémenter respectivement la classe ou
l'interface instanciée.
new Classe([Liste d'arguments]) {
// Instructions de la classe anonyme...
};
new Interface() {
// Instructions de la classe anonyme...
};
La déclaration d'une classe anonyme doit être toujours
suivie d'un point virgule immédiatement après son accolade
fermante, sans quoi une erreur de compilation serait
générée.
Les classes anonymes obéissent aux mêmes restrictions que
les classes locales et de plus, ne peuvent ni être
abstraites (abstract) ni être statiques (static). Par
contre, elles portent toujours implicitement le modificateur
final.
En fait, aucun modificateur n'est permis dans une
déclaration de classe anonyme.
Dans le cas d'une extension, la classe anonyme doit
outrepasser une à plusieurs des méthodes de la classe à
instancier. La surcharge et la définition d'une nouvelle
méthode ne sont pas permis sinon elles provoqueraient une
erreur de compilation.
Dans le cas d'une implémentation, la classe anonyme doit
définir chacune des méthodes abstraites de l'interface à
instancier, sinon une erreur de compilation se produira.
La classe A peut accéder à tous les champs et toutes les
méthodes des calsses C et D. En revanche, il ne peut accéder
qu'aux champs et méthodes des classes B et E qui existent
dans la délcaration de la classe que B ou E implémentent ou
étendent. De plus, la visibilité de la classe F est limitée
à la méthode qui l'a contient.
Les classes internes B,C,E,F peuvent accéder à tous les
champs et toutes les méthodes de la classe A. La classe D ne
peut accéder qu'au champs et méthodes statiques de la classe
A.
Finalement, l'accès par des classes anonymes ou de méthode,
à des variables locales à une méthode n'est possible que si
ces dernières sont déclarées comme
final
.
© Université de Marne-la-Vallée