:: Enseignements :: Master :: M1 :: 2007-2008 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Quelques notes pour le TD1 |
Modificateur de visibilité/accessibilité
Il existe quatre modificateurs de visibilité :
-
un membre sans modificateur est visible par toutes les
classes du même paquetage.
-
un membre
private
n'est visible qu'à l'intérieur de la classe.
-
un membre
protected
est visible par les classes héritées et celles du même
paquetage.
-
un membre
public
est visible par tout le monde
Il existe un ordre de visibilité
private < rien < protected < public
Exemple:
package pack1;
public class A{ public int champPubl; protected int
champProt; int champDef; private int champPriv; ... }
/////////////////////////
package pack1;
public class D extends A{
}
/////////////////////////
package pack1;
public class C{
}
/////////////////////////
package pack2; import pack1.A;
public class B extends A{
}
/////////////////////////
package pack2; import pack1.A;
public class E{
}
|--------------------------------------------|
| visible dans | A | B | C | D | E |
|--------------------------------------------|
| champPubl | oui | oui | oui | oui | oui |
|--------------------------------------------|
| champProt | oui | oui | oui | oui | × |
|--------------------------------------------|
| champDef | oui | × | oui | oui | × |
|--------------------------------------------|
| champPriv | oui | × | × | × | × |
|--------------------------------------------|
Visibilité et maintenance
Quelques règles :
-
un champ n'est jamais
protected
ou
public
-
la visibilité de paquetage est utilisée si une
classe partage des détails d'implantation avec une
autre (exemple: des classes internes)
-
une méthode n'est
public
que si nécessaire
-
une méthode
protected
permet d'implanter un service commun pour les
sous-classes si celui-ci ne peut être écrit hors de
la classe avec une visibilité de paquetage.
Membre statique
Une classe a la possibilité de déclarer des membres (champs,
méthodes, classes internes) statiques (mot-clef
static
), qui sont liés à la classe et non à une instance
particulière. Les membres statiques sont utilisés sans
instance de la classe. Tout code utilisé dans les membres
statiques est utilisé dans un contexte statique i.e. il ne
peut faire référence à l'instance courante (
this
).
Constante
En Java, on utilise une variable
static
et
final
(donc une variable typée) pour définir une constante.
L'évaluation des constantes est effectuée au chargement de
la classe.
Annotation
Une annotation permet de marquer certains éléments du
langage Java afin de leur ajouter une propriété
particulière. Ces annotations peuvent ensuite être utilisées
à la compilation ou à l'exécution pour automatiser certaines
tâches...
Une annotation peut être utilisée sur plusieurs types
d'éléments (
package
,
class
,
interface
,
enum
,
annotation
, constructeur, méthode, paramètre, champs d'une classe ou
variable locale). Plusieurs annotations différentes peuvent
être utilisées sur un même élément mais on ne peut pas
utiliser deux fois la même annotation. En général
l'annotation est placée devant la déclaration de l'élément
qu'elle marque.
L'annotation
@Override
ne peut être utilisée que sur une méthode afin de préciser
au compilateur que cette méthode est redéfinie et doit donc
cacher une méthode héritée d'une classe parente. Si ce n'est
pas le cas (par exemple si une faute de frappe s'est glissée
dans le nom de la méthode), le compilateur doit afficher un
erreur (et donc faire échouer la compilation).
Cette annotation est doublement utile car non seulement elle
permet d'éviter des erreurs bêtes, mais elle rend également
le code plus lisible en distinguant les méthodes redéfinies.
Tests d'égalité
-
Les opérateurs de comparaison
==
et
!=
testent les valeurs des variables :
-
pour les types primitifs, on teste leurs valeurs
-
pour les types objets, on teste les valeurs de leurs
références
Exemple :
Truck a ; a=new Truck() ; Truck b ; b=a ; Truck c=new
Truck() ; a==b ; // true car même référence b==c ; //
false a==c ; // false
-
boolean equals()
Pour comparer sémantiquement deux objets, la classe
correspondante doit redéfinir la méthode
equals(Object)
. La méthode
equals
de
Object
teste les références. La plupart des classes de données de
l'API redéfinissent la méthode
equals
:
Point a=new Point(2,2) ; Point b=new Point(2,2) ;
a.equals(b) ; // true a==b ; // false
Exemple de comparaison d'objets en fonction de leur champ
value
.
public class MyInteger {
public MyInteger(int value) {
this.value = value ;
}
@Override public boolean equals(Object o) {
if ( !(o instanceof MyInteger)) return false ;
return value ==((MyInteger) o).value ;
}
private final int value ;
public static void main(String[ ] args) {
MyInteger i = new MyInteger(3) ;
MyInteger j = new MyInteger(3) ;
System.out.println(i == j) ; // false, compare les références
System.out.println(i.equals(j)) ; // true, compare les contenues
}
}
-
Pourquoi ne pas écrire
equals(MyInteger)
?
public class MyInteger {
public MyInteger(int value){
this.value = value ;
}
public boolean equals(MyInteger i){
// pas @Override
return value == i.value ;
}
private final int value ;
public static void main(String[ ] args) {
MyInteger m1 = new MyInteger(3) ;
List<MyInteger> list = new ArrayList<MyInteger>() ;
list.add(new MyInteger(3)) ;
System.out.println(list.contains(m1)) ; //renvoie false car list appelle
// Object.equals(Object) qui compare les références! !
}
}
equals(MyInteger)
ne redéfinit pas
equals(Object)
, donc il n'y a pas de polymorphisme !
-
int hashCode()
renvoie un entier qui peut être utilisé comme valeur de
hachage de l'objet. Permet aux objets d'être utilisés dans
les tables de hachage.
public class Point {
public Point(int x,int y){
this.x=x;
this.y=y;
}
@Override public int hashCode() {
return x ^ y ;
}
@Override public boolean equals(Object o) {
...
}
}
-
Hashcode
et
equals
. Tout objet redéfinissant
equals
doit redéfinir
hashcode
si l'objet doit être utilisé dans les
Collection
(donc tout le temps).
equals
et
hashcode
doivent vérifier :
-
la méthode
equals
est symétrique, transitive, réflexive
-
x.equals(y)
implique
x.hashcode()==y.hashcode()
-
les valeurs de hashcode doivent, de préférence, être
différentes pour les objets du programme
-
hashcode
doit être rapide à calculer (éventuellement
pré-calculée)
indexOf(Object o)
La méthode
indexOf(Object o)
qui renvoie la position de la première occurrence de l'objet
au sein de la liste courante, ou −1 s'il n'a pu être trouvé
est définie formellement par retourner l'index i tel que
(o==null ? get(i)==null : o.equals(get(i)))
, ou −1 sinon. En effet, la méthode
indexOf
utilise la méthode
equals(Object o)
.
Les ArrayList
La classe
ArrayList
représente des tableaux redimensionnables. L'appel à
l'opération d'ajout d'une entrée dans le tableau résulte en
un tableau de taille suffisante dans lequel la nouvelle
entrée est en dernière position. La parcours d'une
ArrayList
s'effectue à l'aide d'un itérateur.
ArrayList myWords = new Arraylist();
myWords.add("Here");
myWords.add(" is an ");
myWords.add("example");
myWords.add(" ");
myWords.add("of an ArrayList");
ListIterator myIterator = myWords.listIterator();
while (myIterator.hasNext()){
System.out.println(myIterator.next());
}
Le résultat du code ci-dessus est l'affichage de "Here is an
example of an ArrayList".
ArrayList<T>
est en fait un typé: le compilateur indique un avertissement
si le type
<T>
n'est pas précisé. Dans l'exemple précédent, il faut
indiquer lors de la déclaration de
myWords
que ce sont des
String
qui seront stockées:
ArrayList
<String>myWords = new Arraylist();
.
Le tri d'une
ArrayList
peut se faire à l'aide de l'appel à la méthode
Collections.sort(myArrayList)
si les éléments de ma
ArrayList
sont comparables (ce qui est le cas pour les
String
).
© Université de Marne-la-Vallée