Vous êtes sur la page 1sur 42

Programmation Générique

En Java

Préparé par : HASSOUNI Larbi


Objectifs
• Comprendre l’intérêt de la programmation générique
• Etre capable d’implémenter les classes et méthodes
génériques
• Connaître les limites de la programmation générique en
Java
• Comprendre la relation entre les types générique et
l’héritage

L. HASSOUNI 2
Classes paramétrées et génériques
• La classe ArrayList est une classe paramétrée

• Elle possède un paramètre, noté Base_Type, qui peut être


remplacé par n’importe quel type référence pour obtenir
une classe pour ArrayLists avec le type spécifié.

• Dépuis la version 5.0, Java permet la définition de classes


avec des types paramètres.

•Ces classes qui ont un type paramètre sont


appelées classes paramètrées ou définitions
génériques ou tout simplement “génériques”

L. HASSOUNI 3
Avantages de la Généricité

Generics enable you to detect errors at


compile time rather than at runtime.
import java.util.Date;
public class MyTest1 { Erreur à
public static void main(String[] args) { l'exécution
Comparable c = new Date();
System.out.println(c.compareTo("red"));}}

import java.util.Date;
public class MyTest2 { Erreur à la
public static void main(String[] args) { compilation
Comparable<Date> c = new Date();
System.out.println(c.compareTo("red"));}}

L. HASSOUNI 4
ArrayList is a generic class since JDK 1.5.

L. HASSOUNI 5
1- Are there any compile errors in (a) and (b)?

2- What is wrong in (a)? Is the code in (b) correct?

L. HASSOUNI 6
Classes génériques (suite)
• Une classe définie avec un type paramètre est stockée dans un fichier
et compilée de la même manière que n’importe quelle classe.

• Une fois une classe paramètrée est compilée, elle peut être utilisée
comme n’importe quelle autre classe.

• Cependant, le type classe liée au type parametre doit


être spécifié avant que la classe ne puisse être utilisée
dans le programme.

• Cette opération est désignée par instanciation d’une


classe générique.

Sample<String> obj = new Sample<String>();


L. HASSOUNI 7
Définition d’une classe avec un type parameter(1)
public class Sample<T> { public class TestSample {
private T data; public static void main(String[] args)
// T est paramètre pour un type {
Sample<String> s = new Sample<>();
public void setData(T data){
s.setData("Bonjour");
this.data = data; System.out.println(s);
}
public T getData(){ Sample<Date> dates = new Sample<>();
return data; dates.setData(new Date());
} System.out.println(dates);

public String toString(){


}
return data.toString();
}
}

L. HASSOUNI 8
Définition d’une classe avec un type parameter(2)
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<>();
Box<String> stringBox = new Box<>();

integerBox.add(new Integer(10));
stringBox.add(new String("Hello World"));

System.out.printf("Integer Value :%d\n\n", integerBox.get());


System.out.printf("String Value :%s\n", stringBox.get());
}}

L. HASSOUNI 9
Définition d’une classe avec un type paramètre (suite)
• Une classe définie avec un type paramètre est appelé classe
générique ou classe paramétrée.

• Le type paramètre est mis entre parenthèses


angulaires(<>) après le nom de la classe dans l’entête de
la classe.

• N’importe quel mot qui n’est pas un mot clé peut être
utilisé comme type paramètre, mais par convention, le
type paramètre commence par une lettre majuscule.

• Le type paramètre peut être utilisé comme n’importe


quel autre type dans la définition de la classe.

L. HASSOUNI 10
L’option de Compilation -Xlint

•Plusieurs pièges peuvent être rencontrés


lorsqu’on travaille avec des types paramètres.
•Compiler avec l’option -Xlint permet d’obtenir plus
d’informations de diagnostique sur n’importe quel
problème ou problème potentiel dans le code.
javac –Xlint Sample.java

L. HASSOUNI 11
Définition d’une classe générique: Exemple

L. HASSOUNI 12
Définition d’une classe générique: Exemple(suite)

L. HASSOUNI 13
Utilisation d’une classe générique: Exemple

L. HASSOUNI 14
Utilisation d’une classe générique: Exemple(suite)

Program Output:

L. HASSOUNI 15
Le nom d’un constructeur générique n’a pas de type paramètre!!!

• Malgré que le nom d’une classe paramètrée est suivie par un type
parametre qui lui est attaché, le type parametre n’est pas utilisé dans
l’entête de la définition de son constructeur:
public Pair<T>()
• Un conctructeur peut utiliser le type parameter comme le type d’un
paramètre de ce constructor,mais dans ce cas les parentheses
angulaires ne sont pas utilsées:
public Pair(T first, T second)
• Cependant, lorsqu’une classe générique est instanciée, les
parenthèses angulaires sont utilisées:
Pair<String> pair = new Pair<String>("Happy", "Day");

L. HASSOUNI 16
Un type primitif ne peut pas correspondre à un type paramètre!!!

• Le type concret qui correspond à un type paramètre doit


toujours être un type référence:

• Il ne peut pas être un type primitif tel que int, double, ou char

• Cependant, avec l’auto-boxing (emballage), la restriction devient


très limitée.

• Note: les types références incluent les tableaux.

L. HASSOUNI 17
Limitations sur l’utilisation du type paramètre

•A l’intérieur de la définition d’une classe paramétrée,


il y a des places où le type paramètre ne peut pas
être utilisé.
•En particulier, le type paramètre ne peut pas être
utilisé dans une expression simple utilisant new pour
créer un nouveau objet
•Par exemple, le type parametre ne peut pas
être comme un nom de constructeur:
T object = new T();
T[] a = new T[10];

L. HASSOUNI 18
Limitations sur l’instanciation d’une classe générique
• Les tableaux du type ci-dessous sont illégales:
Pair<String>[] a =
new Pair<String>[10];

• Malgré le fait qu’il soit raisonable de créer des tableaux


de ce genre, ce n’est pas autorisé étant donné la façon
dont sont implémentées les classes génériques en Java.

L. HASSOUNI 19
Utilisation des Classes génériques et l’auto-boxing

L. HASSOUNI 20
Utilisation des Classes génériques et l’auto-boxing(suite)

Program Output:

L. HASSOUNI 21
Types Parametres multiples

•La definition d’une classe générique peut avoir un


nombre quelconque de types paramètres.
• Plusieurs types paramètres peuvent être listés entre les
parenthèses angulaires et séparés par des virgules.

L. HASSOUNI 22
Type Paramètres multiples (suite)

L. HASSOUNI 23
Type Paramètres multiples (suite)

L. HASSOUNI 24
Classes génériques et Exceptions

• Il n’est pas permis de créer une classe générique avec


Exception, Error, Throwable, ou n’importe quelle
sous classe de Throwable

• On ne peut pas créer une classe générique dont les objets


instances sont des throwable

public class GEx<T> extends Exception

• L’exemple ci-dessus engendrera une erreur à la compilation.

L. HASSOUNI 25
Utilisation d’une classe générique avec deux Types Paramètres

Program Output:
L. HASSOUNI 26
L. HASSOUNI 27
Limitation des types références correspondant à
un type paramètre
• Des fois il est souhaitable de limiter les types références
destinés à remplacer un type paramètre T.
•Par exemple, pour s’assurer que seules les
classes qui implémentent l’interface
Comparable sont utilisés pour remplacer le
type parametre T, il faut définir la classe comme
suit:
public class RClass<T extends Comparable>
• “extends Comparable" sert de frontière pour les
types références correspondant au type paramètre T.
• N’importe quel essai de remplacer le type T par un type
reference qui n’implémente pas l’interface
Comparable engendrera une erreur à la compilation.
L. HASSOUNI 28
Limitation des types références correspondant à un
type paramètre (suite)
• Une frontière du type paramètre peut être définie par le
nom d’une classe plus tôt que par le nom d’une interface
• Seules les sous classes de la classe frontière peuvent correspondre
au type parameter:
public class ExClass<T extends Class1>

• Une expression frontière peut contenir plusieurs interfaces


mais au plus une classe.
• S’il ya plusieurs types paramètres, la syntaxe est la suivante:
public class Two<T1 extends Class1, T2 extends
I1 & I2>

L. HASSOUNI 29
Limitation des types références correspondant à un
type paramètre (suite)

L. HASSOUNI 30
Interfaces génériques
• Une interface peut avoir un ou plusieurs type paramètres.
• Les details et la notation sont les mêmes que pour une
classe avec des types paramètres.

L. HASSOUNI 31
Méthodes génériques
• Lorsqu’une classe générique est définie, le type paramètre
peut être utilisé dans les definitions des méthodes de cette
classe générique.
• En addition, une méthode générique peut être définie avec
ses propres types paramètres qui ne sont types paramètres
d’aucune classe
•Une méthode génerique peut être membre d’une
classe ordinaire ou membre d’une classe
génerique qui a un autre type paramètre.
•Le type paramètre d’une méthode génerique est
local à cette méthode, et non à la classe.

L. HASSOUNI 32
Méthodes génériques (suite)
• Le type parametre doit être placé entre parenthèses
angulaires après tous les modificateurs, et avant le type
de retour
public static <T> T genMethod(T[] a)
• Lorsqu’une méthode générique est invoquée, son nom est
préfixé avec le type reference correspondant au type
paramètre, mis entre parenthèses angulaire.
String s = NonG.<String>genMethod(c);

L. HASSOUNI 33
Exemple de méthode générique
import java.util.Arrays;

public class GenericMethodTest


{
// generic method printArray
public static < E > void printArray( E[] inputArray )
{
// Display array elements
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}

L. HASSOUNI 34
public static void main( String args[] ) {
// Create arrays of Integer, Double and Character
Integer[] intArray = { 5, 3, 2, 4, 1 };
Double[] doubleArray = { 3.3, 2.2, 4.4, 1.1 };
Character[] charArray = { 'F', 'B', 'A', 'C', 'E', 'D'};

System.out.println( "Array integerArray contains:" );


printArray( intArray ); // pass an Integer array

System.out.println( "\nArray doubleArray contains:" );


printArray( doubleArray ); // pass a Double array

System.out.println( "\nArray characterArray contains:");


printArray( charArray ); // pass a Character array

System.out.println( "\n\n====Arrays sorted======" );


Arrays.sort(intArray);
printArray( intArray );
Arrays.sort(doubleArray);
printArray( doubleArray );
Arrays.sort(charArray);
printArray( charArray ); } }
L. HASSOUNI 35
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}

public class Util {


public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}

L. HASSOUNI 36
public class TestGenericMethod {

public static void main(String[] args) {


Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);
System.out.println(same);

Pair<Integer, String> p3 = new Pair<>(1, "orange");


Pair<Integer, String> p4 = new Pair<>(1, "orange");
boolean notSame = Util.compare(p3, p4);
System.out.println(notSame);
}

L. HASSOUNI 37
Exemple de méthode générique avec limitation de type
public class MaximumTest{
// determines the largest of three Comparable objects
public static <T extends Comparable<T>> T maximum(T x, T y, T z){
T max = x; // assume x is initially the largest
if ( y.compareTo( max ) > 0 ){
max = y; // y is the largest so far
}
if ( z.compareTo( max ) > 0 ){
max = z; // z is the largest now
}
return max; // returns the largest object
}
public static void main( String args[] ){
System.out.printf( "Max of %d, %d and %d is %d\n\n",
3, 4, 5, maximum( 3, 4, 5 ) );

System.out.printf( "Maxm of %.1f,%.1f and %.1f is %.1f\n\n",


6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );

System.out.printf( "Max of %s, %s and %s is %s\n","pear",


"apple", "orange", maximum( "pear", "apple", "orange" ) );
}}

L. HASSOUNI 38
Exemple de méthode générique avec un nombre variable
d'arguments
public class MinimumTest{
public static <T extends Comparable<T>> T minimum(T... x){
T min = x[0]; // assume x is initially the largest
for (T elemnent : x)
if ( elemnent.compareTo( min ) < 0 ){
min = elemnent; // y is the largest so far
}
return min; // returns the smallest object
}
public static void main( String args[] ){
System.out.printf( "Min of %d, %d and %d is %d\n\n",
3, 4, 5, minimum( 3, 4, 5 ) );

System.out.printf( "Min of %.1f,%.1f and %.1f is %.1f\n\n",


6.6, 8.8, 7.7, minimum( 6.6, 8.8, 7.7 ) );

System.out.printf( "Min of %s, %s and %s is %s\n","pear",


"apple", "orange", minimum( "pear", "apple", "orange" )
); }}
L. HASSOUNI 39
Héritage et classes génériques
• Une classe générique peut être définie comme une sous-
classe d’une classe ordinaire ou d’une autre classe
générique
•Comme avec une classe ordinaire, un objet
instance d’une sous classe est aussi instance de
la superclasse
• Etant données deux classes: A et B, et étant donnée G:
une classe générique, il n’ya aucune relation entre G<A>
et G<B>
•Ceci est vrai quelque soit la relation qui peut
exister entre les classes A et B, même si la
classe B est une sous-classe de la classe A
L. HASSOUNI 40
Classe générique dérivée: Exemple

L. HASSOUNI 41
Classe générique dérivée: Exemple (Suite)

Program Output:
L. HASSOUNI 42

Vous aimerez peut-être aussi