Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres bornés.

Slides:



Advertisements
Présentations similaires
Le mécanisme des exceptions
Advertisements

1 Quelques précisions sur l'héritage. 2 Signification de super.f() appel à la méthode f() masquée super : désigne l'objet appelant comme s'il était de.
SI3 MAM3 Hydro Nathan Cohen Igor Litovsky Christophe Papazian
Au programme du jour …. Un peu plus de structures de données
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Approfondissement du langage
Programmer en JAVA par Tama
JAV - TD 6 Structures de données JAVA
Chapitre IV Object, interfaces, classes imbriquées.
Chapitre III Héritage (début)
VI) exemple: Les astres…
Principes de programmation (suite)
Classes locales classes définies à l'intérieur d'un bloc de code,
Cours programmation-orientée objet en Java
Structures collectives en Java
IPA – Catherine Faron Zucke et Anne Marie Deryr. suite ordonnée d'éléments de taille variable ArrayList liste; liste = new ArrayList (); Ne peuvent contenir.
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Les collections d'objets
POO-L3 H. Fauconnier1 Chapitre IV 1. classe Object, clonage 2. interfaces 3. classes internes et imbriquées.
POO-L3 H. Fauconnier1 C) Méthodes: Redéfinition Un classe hérite des méthodes des classes ancêtres Elle peut ajouter de nouvelles méthodes Elle peut surcharger.
Généricité (fin) collections…. GénéricitéPOO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Types paramètres bornés.
Exceptions (fin) Généricité
POO-L3 H. Fauconnier1 Tableau et héritage Y[] yA=new Y[3]; X[] xA=yA; //ok xA[0]=new Y(); xA[1]=new X(); //non xA[1]=new Z(); //non Object XX[]int[] YZY[]Z[]
Premier cours (23 septembre). Cours programmation- orientée objet en Java Licence dinformatique Hugues Fauconnier
Chapitre VII Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres.
Chapitre III Héritage. POO-L3 H. Fauconnier2 Chapitre III: Héritage A) Extensions généralités Affectation et transtypage B) Méthodes Surcharge et signature.
Interfaces (fin) classes locales et internes, Object, clonage.
1 Objectifs de ce cours (I21) Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde Résumé du cours précédent.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
Rappels Java.
Présentation Structures de Données et TDA
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
POO-L3 H. Fauconnier1 Supplément gratuit…. POO-L3 H. Fauconnier2 Entrée-sortie public static void main(String[] args) { // sortie avec printf ou double.
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Indexation et Recherche d'Information
Cours du 22 novembre généricité. Chapitre VII Généricité.
Chapitre III Héritage. POO-L3 H. Fauconnier2 Chapitre III: Héritage A) Extensions généralités Affectation et transtypage B) Méthodes Surcharge et signature.
Chapitre III Héritage. POO-L3 H. Fauconnier2 Chapitre III: Héritage A) Extensions généralités Affectation et transtypage B) Méthodes Surcharge et signature.
Cours 4 Héritage (suite).
Cours 11 Threads. Chapitre X threads threadPOO-L3 H. Fauconnier3 Threads threads: plusieurs activités qui coexistent et partagent des données exemples:
Cours 6 décembre. Collections POO-L3 H. Fauconnier3 Collections types de données interfaces implémentations algorithmes Interfaces:
Cours 8 (18 novembre 2011) exceptions. héritagePOO-L3 H. Fauconnier2 Tableau et héritage Y[] yA=new Y[3]; X[] xA=yA; //ok xA[0]=new Y(); xA[1]=new X();
Cours 5 Héritage, Interfaces, classes internes. POO-L3 H. Fauconnier2 La classe Object Toutes les classes héritent de la classe Object Object méthodes:
Java, les objets : tout de suite ! Rassembler, grouper les objets
Les méthodes en java • Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. • Une méthode pour être utilisée.
Cours 7 Divers et exceptions. Chapitre V Enumeration, tableaux, conversion de types, noms.
J201 (JOC) Java Avancé juin 2007 ~ Brigitte Groléas ~
Objectifs À la fin de ce cours, vous serez capables de :
COURS DE PROGRAMMATION ORIENTEE OBJET :
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
Cours n°3 rappels. POO-L3 H. Fauconnier2 Entrée-sortie public static void main(String[] args) { // sortie avec printf ou double a = 5.6d ; double b =
La notion de type revisitée en POO
Cours du 3/12. Threads threadPOO-L3 H. Fauconnier3 Threads  threads: plusieurs activités qui coexistent et partagent des données exemples:  pendant.
Cours 9 Exceptions (fin) Généricité. POO-L3 H. Fauconnier2 Chaînage d'exceptions  Une exception peut être causée par une autre.  il peut être utile.
11/04/ L'héritage Cours 7 Cours 7.
Variables et accès en Java. Déclaration des variables final transient static private Printer hp; transient => ne doivent pas être sérialisées volatile.
Cours 7 Classes locales Clonage Divers: tableaux.
Tutorat en bio-informatique
Les classes présenté par: RAHMOUNE RIME / ZEKRI SELMA.
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Cours du 5 novembre.
Héritage H. Batatia. plan Notion (que signifie l’héritage) Ecriture en java Héritage multiple (interdit) Instanciation (partie propre et partie héritée)
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Héritage Conception par Objet et programmation Java
Chapitre 21 Collections partie III Set Une collection qui contient des éléments uniques. Deux implémentation :  HashSet : stock les éléments.
Chapitre VII Généricité. POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Types paramètres bornés 4. Méthodes.
Collections. POO-L3 H. Fauconnier2 Collections  types de données interfaces implémentations algorithmes  Interfaces:
Transcription de la présentation:

Généricité

POO-L3 H. Fauconnier2 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres bornés

GénéricitéPOO-L3 H. Fauconnier3 Principes Paramétrer une classe ou une méthode par un type: une pile de X En java toute classe étant dérivée de Object, cela permet d'obtenir une forme de généricité sans contrôle des types une pile d'Object La généricité en Java est un mécanisme « statique », la généricité existe dans d'autres langages (exemple C++ et Ada) (mais de façon différente)

GénéricitéPOO-L3 H. Fauconnier4 Exemple: FileFile public class Cellule { private Cellule suivant; private E element; public Cellule(E val) { this.element=val; } public Cellule(E val, Cellule suivant){ this.element=val; this.suivant=suivant; } public E getElement(){ return element;} public void setElement(E v){ element=v; } public Cellule getSuivant(){ return suivant;} public void setSuivant(Cellule s){ this.suivant=s; }

GénéricitéPOO-L3 H. Fauconnier5 Suite class File { protected Cellule tete; protected Cellule queue; private int taille=0; public boolean estVide(){ return taille==0; } public void enfiler(E item){ Cellule c=new Cellule (item); if (estVide()) tete=queue=c; else{ queue.setSuivant(c); queue=c; } taille++; } //..

GénéricitéPOO-L3 H. Fauconnier6 suite public E defiler(){ if (estVide()) return null; Cellule tmp=tete; tete=tete.getSuivant(); taille--; return tmp.getElement(); } public int getTaille(){ return taille; }

GénéricitéPOO-L3 H. Fauconnier7 Usage Cellule cel=new Cellule (23); File fi=new File (); File fs=new File (); File fobj=new File (); String[] st={"zéro","un","deux", "trois","quatre","cinq"}; for(int i=0;i<st.length;i++){ fs.enfiler(st[i]); fi.enfiler(i); }

GénéricitéPOO-L3 H. Fauconnier8 Remarques Contrôle de type fs.enfiler(4) est refusé à la compilation Diamond <> : File fi=new File<>(); Est équivalent à : File fi=new File (); (inférence de types)

Remarques: Une déclaration de type générique peut avoir plusieurs paramètres: Map Terminologie: Paramètre type T dans List Paramètre argument Integer dans List Type paramétré: List POO-L3 H. Fauconnier9

Types génériques, pourquoi? Vérification de type: List myIntList = new LinkedList(); myIntList.add(new Integer(0)); Integer x = (Integer) myIntList.iterator().next(); Et: List myIntList = new LinkedList (); myIntList.add(new Integer(0)); x=myIntList.iterator().next(); POO-L3 H. Fauconnier10

GénéricitéPOO-L3 H. Fauconnier11 Typage Une invocation ne crée pas un nouveau type: (fs.getClass()==fi.getClass()) est vrai la classe est ici File il s'agit surtout d'un contrôle (effectué à la compilation) à l'exécution fi n'a plus aucune information sur quelle invocation a permis sa construction

Invocation Pour le type paramétré: public interface List { void add(E x); Iterator iterator(); } public interface Iterator { E next();boolean hasNext();} L invocation avec un argument type: List pourrait (C++)correspondre à: public interface IntegerList { void add(Integer x); Iterator iterator(); } Mais… une déclaration d'un type paramétré crée un seul type (qui est compilé comme un tout) et il ny a pas de type nouveau pour List (uniquement des vérifications à la compilation POO-L3 H. Fauconnier12

GénéricitéPOO-L3 H. Fauconnier13 Conséquences Aucune instanciation n'est possible pour un type argument Dans l'exemple: E v=new E(); est impossible Pas de tableau de E

GénéricitéPOO-L3 H. Fauconnier14 Exemple public E[] toArray(File f){ E[] tab=new E[f.getTaille()]; //non for(int i=0;i<f.getTaille();i++) tab[i]=f.defiler(); } Comment construire un tableau sans connaître le type de base? La classe Array et la méthode Array.newInstance() permettraient de résoudre ce problème (mais sans contrôle de type) On peut aussi utiliser la classe Object.

GénéricitéPOO-L3 H. Fauconnier15 Object public static Object[] toArray(File f){ Object[] tab=new Object[f.getTaille()]; for(int i=0;i<f.getTaille();i++) tab[i]=f.defiler(); return tab; } mais on perd l'avantage du contrôle de type.

GénéricitéPOO-L3 H. Fauconnier16 Contrôle du type Pourtant, on peut passer un objet d'un type avec paramètre à une méthode. Comment se fait le passage des paramètres? le compilateur passe le type le plus général ( Object ) et utilise le cast pour assurer le contrôle du typage (« type erasure »)

Compléments Types bruts (« raw ») est un héritage des versions avant généricités: File brutFile =new File(); Est un type brut File fs=brutFile; //ok mais warning POO-L3 H. Fauconnier17

GénéricitéPOO-L3 H. Fauconnier18 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres bornés

GénéricitéPOO-L3 H. Fauconnier19 Types génériques imbriqués public class FileSimpleChainageb { public class Cellule{ private Cellule suivant; private E element; public Cellule(E val) { this.element=val; } public Cellule(E val, Cellule suivant){ this.element=val; this.suivant=suivant; } public E getElement(){ return element; } public void setElement(E v){ element=v; }//...

GénéricitéPOO-L3 H. Fauconnier20 Suite public Cellule getSuivant(){ return suivant; } public void setSuivant(Cellule s){ this.suivant=s; } protected Cellule tete; protected Cellule queue; private int taille=0; public boolean estVide(){ return taille==0; } public int getTaille(){ return taille; }

GénéricitéPOO-L3 H. Fauconnier21 Fin… public void enfiler(E item){ Cellule c=new Cellule(item); if (estVide()) tete=queue=c; else{ queue.setSuivant(c); queue=c; } taille++; } public E defiler(){ if (estVide()) return null; Cellule tmp=tete; tete=tete.getSuivant(); taille--; return tmp.getElement(); } }

GénéricitéPOO-L3 H. Fauconnier22 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres bornés

Méthode génériques public class Paire { private K key; private V value; public Paire(K key, V value) { this.key = key;this.value = value;} //… } Comparer des paires: public class Util{ public static boolean compare(Paire p1, Paire p2) { return p1.getKey().equals(p2.getKey()) && p1.getValue().equals(p2.getValue()); } Et: Pair p1 = new Pair<>(1, "pomme"); Pair p2 = new Pair<>(2, "banane"); Boolean bol = Util. compare(p1, p2); POO-L3 H. Fauconnier23

Méthodes génériques Mais aussi: Paire p1 = new Paire<>(1, "pomme"); Paire p2 = new Paire<>(2, "banane"); Boolean bol = Util.compare(p1, p2); Inférence de type: Déterminer le type « le plus spécifique » (comme pour la surcharge) POO-L3 H. Fauconnier24

GénéricitéPOO-L3 H. Fauconnier25 Méthodes génériques Supposons que l'on veuille convertir en tableau une File de E on a vu précédemment que l'on ne pouvait ni instancier un objet E ni créer un tableau de E on peut cependant passer un tableau de la taille appropriée à une méthode qui retourne ce tableau:

GénéricitéPOO-L3 H. Fauconnier26 enTableau1 public E[] enTableau1(E[] tab){ Object[] tmp = tab; int i=0; for(Cellule c= tete; c != null && i< tab.length; c=c.getSuivant()) tab[i++] = c.getElement(); return tab; } enTableau1 est une nouvelle méthode de File: File fs=new File (); String[] u; u=fs.enTableau1(new String[fs.getTaille()]);

GénéricitéPOO-L3 H. Fauconnier27 enTableau Mais, il faut ici que le tableau passé en paramètre soit un tableau de E, alors qu'un tableau d'une superclasse de E devrait fonctionner (si F est une superclasse de E un tableau de F peut contenir des objets E). avec une méthode générique:

GénéricitéPOO-L3 H. Fauconnier28 enTableau public T[] enTableau(T[] tab){ Object[] tmp = tab; int i=0; for(Cellule c= tete; c != null && i< tab.length; c=c.getSuivant()) tmp[i++] = c.getElement(); return tab; } la déclaration impose que le type du tableau retourné soit du type du tableau de l'argument Notons que tmp est un tableau d' Object ce qui est nécessaire pour le getSuivant Notons que normalement il faudrait que T soit une superclasse de E (à l'exécution il peut y avoir une erreur). Notons enfin que ' T ' ne sert pas dans le corps de la méthode.

GénéricitéPOO-L3 H. Fauconnier29 Remarque public T[] enTableaubis(T[] tab){ int i=0; for(Cellule c= tete; c != null && i< tab.length; c=c.getSuivant()) tab[i++] = (T)c.getElement(); return tab; } provoque un warning "Cellule.java uses unchecked or unsafe operations". (l'"effacement" ne permet pas de vérifier le type)

GénéricitéPOO-L3 H. Fauconnier30 Avec Reflection… Une autre solution peut être, si on veut créer un vrai tableau, d'utiliser Array.newInstance de la classe: java.lang.reflect

GénéricitéPOO-L3 H. Fauconnier31 Exemple avec ReflectionReflection public E[] enTableau2(Class type){ int taille = getTaille(); E[] arr=(E[])Array.newInstance(type,taille); int i=0; for(Cellule c= tete; c != null && i< taille; c=c.getSuivant()) arr[i++] = c.getElement(); return arr; } on crée ainsi un tableau de "E" "unchecked warning": le cast (E[]) n'a pas le sens usuel pour fs déclaré comme précédemment on aura: String[] u=fs.enTableau2(String.class); //ok Object[] v=fs.enTableau2(Object.class); //non car le type doit être exact

GénéricitéPOO-L3 H. Fauconnier32 Avec une méthode générique public T[] enTableau3(Class type){ int taille = getTaille(); T[] arr=(T[])Array.newInstance(type,taille); int i=0; Object[] tmp=arr; for(Cellule c= tete; c != null && i< taille; c=c.getSuivant()) tmp[i++] = c.getElement(); return arr; }

GénéricitéPOO-L3 H. Fauconnier33 Chapitre VII 1. Principes généraux 2. Types génériques imbriqués 3. Méthodes génériques 4. Types paramètres bornés

Borner le type paramètre Classe: public interface Comparable { public int compareTo(T o); } Une méthode peut vouloir imposer que son type paramètre implémente Comparable: public static > int countGreaterThan(T[] anArray, T elem) { int count = 0; for (T e : anArray) if (e.compareTo(elem) > 0) ++count; return count; } POO-L3 H. Fauconnier34

héritage List ls = new ArrayList (); List lo = new ArrayList (); lo.add( "bonjour"); //ok lo = ls; //1 lo.add(new Object()); //2 String s = ls.get(0); //3 ! Si A est une extension de B, F n'est pas une extension de F : //1 est interdit (Pour les tableaux: si A est une extension de B un tableau de A est une extension de tableau de B. //1 est autorisé, mais ensuite //2 est interdit) POO-L3 H. Fauconnier35

Joker '?' void printCollection(Collection c) { for (Object e : c) { System.out.println(e);} } Ne fonctionne pas avec une Collection Une collection de n'importe quoi ('?') void printCollection(Collection c) { for (Object e : c){ System.out.println(e);} } est possible (n'importe quoi est un objet). POO-L3 H. Fauconnier36

Mais Mais ? étant nimporte quel type on ne peut plus faire « daffectation »: Collection c = new ArrayList (); c.add(new Object()); // erreur compilation ? nest pas « Object »: cest un type inconnu. pour faire un « add » il faudrait que le type du paramètre soit dune extension de ce type inconnu… par pour faire un « get » on est sûr que cest au moins un « Object » POO-L3 H. Fauconnier37

Borner le type paramètre Comme pour les méthodes on peut borner le type paramètre: Une SortedCollection est construite sur des classes E qui implémentent Comparable d'où: interface SortedCollection >{} POO-L3 H. Fauconnier38

GénéricitéPOO-L3 H. Fauconnier39 Exemple static double somme(List l){ double res=0.0; for(Number n:l) res+=n.doubleValue(); return res; } public static void main(String[] st){ List l= new ArrayList (); for(int i=0;i<10;i++)l.add(i); double s=somme(l); //incorrect } (List nest pas une extension de List Mais:

GénéricitéPOO-L3 H. Fauconnier40 Type paramètre borné Il faut que le type argument soit au moins un Number: List une liste constituée de n'importe quel type dérivé de Number static double somme2(List l){ double res=0.0; for(Number n:l) res+=n.doubleValue(); return res; }

GénéricitéPOO-L3 H. Fauconnier41 Types paramètres bornés List indique que le type doit au moins être un Number (tout type qui dérive de Number ) borné par le bas : au moins un Number On peut aussi imposer que le type soit une superclasse d'un autre type List borné par le haut : au plus un Integer (super-classe de Integer )

Remarques a = b Suppose que le type de a est une superclasse du type de b Suppose que le type de b est dune extension du type de a. Pour ajouter un élément de type T dans une liste, il faut que le type des éléments de la liste soit dune superclasse de T: List Pour que lélément de la liste soit affectable à un type T, il faut que le type des éléments de la liste soit dune extension de T: List POO-L3 H. Fauconnier42

GénéricitéPOO-L3 H. Fauconnier43 Exemples File str=new File (); str.enfiler("un"); provoque une erreur à la compilation: enfiler(capture of ?) in generique.File cannot be applied to (java.lang.String) de même: File num=new File (); num.enfiler(Integer.valueOf(12)); en effet File peut être par exemple une File d'un type dérivé de Number. Par contre: File num=new File (); num.enfiler(Integer.valueOf(12)); est correct

GénéricitéPOO-L3 H. Fauconnier44 Quelques explications ? peut correspondre à n'importe quel type enfiler(a) où a est de type A ne peut fonctionner si le type correspondant à ? est dérivé de A de même ? dans ne peut fonctionner car si ? est Y dérivé de X il faut un paramètre d'une classe dérivée de Y par contre ? dans ne pouvant correspondre qu'à une classe "avant" X, tout Z dérivé de X fonctionne

GénéricitéPOO-L3 H. Fauconnier45 Mais inversement pour la valeur retournée (avec la méthode défiler par exemple) pour quelque soit le type X correspondant on peut l'affecter à Object et à X idem pour mais pour si Z correspond à ? pour T un type quelconque on ne peut savoir si T peut être affecté par un Z

GénéricitéPOO-L3 H. Fauconnier46 Explications sur lerreur enfiler(capture of ?) in generique.File cannot be applied to (java.lang.String) signifie que le type de str est File qui n'est pas compatible avec String Capture de ?: le type inconnu correspondant à ?

GénéricitéPOO-L3 H. Fauconnier47 Super… Exemple: SortedCollection est composée d'éléments du type E et ces éléments peuvent être comparés. Mais > est trop fort: il suffit que E extends Comparable pour T égal à E ou T superclasse de E (si E extends Comparable a fortiori on peut comparer les éléments de E) d'où déclaration >

GénéricitéPOO-L3 H. Fauconnier48 Hiérarchie des classes List est une super classe de List Et: List

GénéricitéPOO-L3 H. Fauconnier49 Inférence de type Comment invoquer une méthode générique? Inférence de type: déterminer les arguments type pour une invocation Le plus spécifique Exemple: static T identite(T obj){ return obj; }

GénéricitéPOO-L3 H. Fauconnier50 Invocations (inférence) On peut explicitement préciser le type: String s1="Bonjour"; String s2= Main. identite(s1); Mais le compilateur peut, lui-même, trouver le type le plus spécifique: String s1=identite("Bonjour"); On aura: Object o1=identite(s1); //ok Object o2=identite((Object)s1); //ok s2=identite((Object) s1); //non!!! s2=(String)identite((Object) s1);//ok

GénéricitéPOO-L3 H. Fauconnier51 Effacement Mécanisme de l'effacement ("erasure") Pour chaque type générique il n'y a qu'une classe: Cellule et Cellule sont la même classe Effacement: Pour un paramètre type: Non borné: (-> Object) Cellule -> Cellule Cellule est un type brut Borné: (-> la borne) -> Object -> Number Le compilateur remplace chaque type paramètre par son effacement

GénéricitéPOO-L3 H. Fauconnier52 Effacement Si le résultat de l'effacement du générique ne correspond pas au type paramètre, le compilateur génère un cast: par effacement le type paramètre de File est Object pour un "defiler" sur un objet File le compilateur insère un cast sur String

GénéricitéPOO-L3 H. Fauconnier53 Effacement A cause de l'effacement, rien de ce qui nécessite de connaître la valeur d'un argument type n'est autorisé. Par exemple: on ne peut pas instancier un type paramètre: pas de new T() ou de new T[] on ne peut pas utiliser instanceof pour une instance de type paramétré on ne peut pas créer de tableau sur un type paramétré sauf s'il est non borné new List [10] est interdit mais new List [10] est possible.

GénéricitéPOO-L3 H. Fauconnier54 Effacement les "cast" sont possibles mais n'ont pas la même signification que pour les types non paramétrés: le cast est remplacé par un cast vers le type obtenu par effacement et génère un "unchecked warning" à la compilation. Exemple: on peut caster paramètre File vers un File pour un enfiler (ce qui génère le warning) A l'exécution si le type effectif est File cela passe… mais le defiler provoquera un ClassCastException.

GénéricitéPOO-L3 H. Fauconnier55 Application: surcharge avoir la même signature s'étend aux méthodes avec variables types même signature pour des variables types = même type et même borne (modulo bien sûr renommage!) signatures équivalentes par annulation: mêmes signatures où l'effacement des signatures sont identiques

GénéricitéPOO-L3 H. Fauconnier56 Surcharge class Base { void m(int x){}; void m(T t){}; void m(String s){}; void m(N n){}; void m(File q){}; } m(int) m(Object) m(String) m(Number) m(File)

GénéricitéPOO-L3 H. Fauconnier57 Et héritage… exemple: class D extends Base { void m(Integer i){} //nouveau void m(Object t){} // redéfinit m(T t) void m(Number n){} // redéfinit m(N n) }

« Reifiable » Type reifiable: linformation sur le type est totalement accessible à lexécution (types non génériques, types bruts, invocations de ? non bornés Type non-reifiable: à cause de leffacement linformation sur le type nest pas entièrement accessible à lexécution: List et List. Pour ces types pas de « instanceof », pas de tableau. POO-L3 H. Fauconnier58

Exemples… public class Node { private T data; public Node(T data) { this.data = data; } public void setData(T data) { this.data = data; } } public class MyNode extends Node { public MyNode(Integer data) { super(data); } public void setData(Integer data) {super.setData(data); } } Et le code: MyNode mn = new MyNode(5); Node n= mn; n.setdata( "Bonjour " ); Integer x = mn.data; POO-L3 H. Fauconnier59

Exemple Après effacement: MyNode mn = new MyNode(5); Node n= (MyNode)mn; //unchecked warning n.setdata( "Bonjour "); Integer x = (String)mn.data ; Appel de setData(Object) et T dans n -> String T pour mn est Integer classCastException POO-L3 H. Fauconnier60

Quelque complications Par effacement on a: public class Node { Private Object data; public Node(Object data) { this.data = data; } public void setData(Object data) { this.data = data; } } public class MyNode extends Node { public MyNode(Integer data) { super(data); } public void setData(Integer data) {super.setData(data); } } Mais, setData de NyNode nest plus une redéfinition de setData de Node (argument) (« bridge ») public class MyNode extends Node { public MyNode(Integer data) { super(data); } public void setData(Object data){ setData((Integer) data;} public void setData(Integer data) {super.setData(data); } } POO-L3 H. Fauconnier61

« bridge » public class MyNode extends Node { public MyNode(Integer data) { super(data); } public void setData(Object data){ setData((Integer) data;} public void setData(Integer data) {super.setData(data); } } POO-L3 H. Fauconnier62

Restrictions Pas dinstanciation de types génériques avec des types primitifs. Pas dinstances de paramètres types Pas de instanceof pour des types paramétrés Pas de tableaux de types paramétrés POO-L3 H. Fauconnier63

Collections

POO-L3 H. Fauconnier65 Collections types de données interfaces implémentations algorithmes Interfaces:

POO-L3 H. Fauconnier66 Collections: les interfaces Les collections sont des interfaces génériques Collection : add, remove size toArray… Collection : Set : éléments sans duplication Set : SortedSet : ensembles ordonnés SortedSet : List : des listes éléments non ordonnés et avec duplication List : Queue : files avec tête: peek, poll (défiler), offer (enfiler) Queue : Map :association clés valeurs Map : SortedMap avec clés triées SortedMap<K,V Certaines méthodes sont optionnelles (si elles ne sont pas implémentées UnsupportedOperationException). UnsupportedOperationException En plus: Iterator : interface qui retourne successivement les éléments next(), hasNext(), remove() Iterator : ListIterator : itérateur pour des List, set(E) previous, add(E) ListIterator :

POO-L3 H. Fauconnier67 Collection public interface Collection extends Iterable { // operations de base int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optionnel boolean remove(Object element); //optionnel Iterator iterator(); // operations des collections boolean containsAll(Collection c); boolean addAll(Collection c); //optionnel boolean removeAll(Collection c); //optionnel boolean retainAll(Collection c); //optionnel void clear(); //optionnel // Array Object[] toArray(); T[] toArray(T[] a); }

POO-L3 H. Fauconnier68 Collection Les collections sont génériques Parcours: On peut parcourir les éléments par « for »: for (Object o : collection) System.out.println(o); Ou avec un Iterator: static void filter(Collection c) { for (Iterator it = c.iterator(); it.hasNext();) if (!cond(it.next())) it.remove(); }

POO-L3 H. Fauconnier69 Collection On peut convertir une collection en tableau En tableaux de Object En tableaux dobjet du type paramètre de la collection Il existe aussi une classe Collections qui contient des méthodes statiques utilesCollections

POO-L3 H. Fauconnier70 Set Interface pour contenir des objets différents Opérations ensemblistes SortedSet pour des ensembles ordonnés SortedSet Implémentations: HashSet par hachage (preformances) HashSet TreeSet arbre rouge-noir TreeSet LinkedHashSet ordonnés par ordre dinsertion LinkedHashSet

POO-L3 H. Fauconnier71 Set public interface Set extends Collection { // opérations de base int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optionnel boolean remove(Object element); //optionnel Iterator iterator(); // autres boolean containsAll(Collection c); // sous-ensemble boolean addAll(Collection c); //optionnel- union boolean removeAll(Collection c); //optionnel- différence boolean retainAll(Collection c); //optionnel- intersection void clear(); //optionnel // Array Object[] toArray(); T[] toArray(T[] a); }

POO-L3 H. Fauconnier72 Exemple: public static void chercheDoublons(String... st){ Set s = new HashSet (); for (String a : st) if (!s.add(a)) System.out.println("Doublon: " + a); System.out.println("il y a "+s.size() + " mots différents: " + s); } public static void chercheDoublonsbis(String st[]){ Set s=new HashSet (); Set sdup=new HashSet (); for(String a :st) if (!s.add(a)) sdup.add(a); s.removeAll(sdup); System.out.println("Mots uniques: " + s); System.out.println("Mots dupliqués: " + sdup); }

POO-L3 H. Fauconnier73 Lists En plus de Collection: Accès par position de lélément Recherche qui retourne la position de lélément Sous-liste entre deux positions Implémentations: ArrayList LinkedList

POO-L3 H. Fauconnier74 List public interface List extends Collection { // accès par position E get(int index); E set(int index, E element); //optional boolean add(E element); //optional void add(int index, E element); //optional E remove(int index); //optional boolean addAll(int index, Collection c); //optional // recherche int indexOf(Object o); int lastIndexOf(Object o); // Iteration ListIterator listIterator(); ListIterator listIterator(int index); // sous-liste List subList(int from, int to); }

POO-L3 H. Fauconnier75 Itérateur pour listes public interface ListIterator extends Iterator { boolean hasNext(); E next(); boolean hasPrevious(); E previous(); int nextIndex(); int previousIndex(); void remove(); //optional void set(E e); //optional void add(E e); //optional }

POO-L3 H. Fauconnier76 Exemple public static void swap(List a, int i, int j) { E tmp = a.get(i); a.set(i, a.get(j)); a.set(j, tmp); } public static void melange(List list, Random rnd) { for (int i = list.size(); i > 1; i--) swap(list, i - 1, rnd.nextInt(i)); }

POO-L3 H. Fauconnier77 Suite… public static List uneMain(List deck, int n) { int deckSize = deck.size(); List handView = deck.subList(deckSize - n, deckSize); List hand = new ArrayList (handView); handView.clear(); return hand; } public static void distribuer(int nMains, int nCartes) { String[] couleurs = new String[]{"pique","coeur","carreau","trèfle"}; String[] rank = new String[] {"as","2","3","4","5","6","7","8", "9","10","valet","dame","roi"}; List deck = new ArrayList (); for (int i = 0; i < couleurs.length; i++) for (int j = 0; j < rank.length; j++) deck.add(rank[j] + " de " + couleurs[i]); melange(deck,new Random()); for (int i=0; i < nMains; i++) System.out.println(uneMain(deck,nCartes)); }

POO-L3 H. Fauconnier78 Map Map associe des clés à des valeurs Map Association injective: à une clé correspond exactement une valeur. Trois implémentations, comme pour set HashMap, HashMap TreeMap, TreeMap LinkedHashMap Remplace Hash

POO-L3 H. Fauconnier79 Map public interface Map { // Basic operations V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); // Bulk operations void putAll(Map m); void clear(); // Collection Views public Set keySet(); public Collection values(); public Set > entrySet(); // Interface for entrySet elements public interface Entry { K getKey(); V getValue(); V setValue(V value); }

POO-L3 H. Fauconnier80 Exemples public static void mapFreq(String... t) { Map m = new HashMap (); for (String a : t) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println("Il y a: " + m.size() + " mots différents:\n"+m); } // ordre arbitraire

POO-L3 H. Fauconnier81 Exemples public static void mapFreq(String... t) { Map m = new TreeMap (); for (String a : t) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println("Il y a: " + m.size() + " mots différents:\n"+m); } // ordre arbitraire

POO-L3 H. Fauconnier82 Exemples public static void mapFreq(String... t) { Map m = new LinkedHashMap (); for (String a : t) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println("Il y a: " + m.size() + " mots différents:\n"+m); } // ordre arbitraire

POO-L3 H. Fauconnier83 Queue Pour représenter une file (en principe FIFO): Insertion: offer -add Extraction: poll - remove Pour voir: peek –element (retourne une valeur - exception PriorityQueue implémentation pour une file à priorité PriorityQueue

POO-L3 H. Fauconnier84 Interface Queue public interface Queue extends Collection { E element(); boolean offer(E e); E peek(); E poll(); E remove(); }

POO-L3 H. Fauconnier85 Exemple public static void compteur(int n) throws InterruptedException { Queue file = new LinkedList (); for (int i = n; i >= 0; i--) file.add(i); while (!file.isEmpty()) { System.out.println(file.remove()); Thread.sleep(1000); }

POO-L3 H. Fauconnier86 Exemple static List heapSort(Collection c) { Queue queue = new PriorityQueue (c); List result = new ArrayList (); while (!queue.isEmpty()) result.add(queue.remove()); return result; }

POO-L3 H. Fauconnier87 Des implémentations HashSet : implémentation de Set comme table de hachage. Recherche/ ajout suppression en temps constant HashSet : TreeSet : SortedSet comme arbre binaire équilibré O(log(n)) TreeSet : ArrayList : liste implémentée par des tableaux à taille variable accès en O(1) ajout et suppression en O(n-i) (i position considérée) ArrayList : LinkedList : liste doublement chaînée implémente List et Queue accès en O(i) LinkedList : HashMap : implémentation de Map par table de hachage ajout suppression et recherche en O(1) HashMap : TreeMap : implémentation de SortedMap à partir d'arbres équilibrés ajout, suppression et recherche en O(log(n)) TreeMap : WeakHashMap : implémentation de Map par table de hachage WeakHashMap : PriorityQueue : tas à priorité. PriorityQueue :

I/O packagePOO-L3 H. Fauconnier88 Comparaisons Interface Comparable contient la méthode public int compareTo(T e) "ordre naturel" Interface Comparator contient la méthode public int compare(T o1, T o2)

I/O packagePOO-L3 H. Fauconnier89 Quelques autres packages System méthodes static pour le système: System entrée-sorties standard manipulation des propriétés systèmes utilitaires "Runtime" exit(), gc() …

I/O packagePOO-L3 H. Fauconnier90 Runtime, Process Runtime permet de créer des processus pour exécuter des commande: exec Runtime Process retourné par un exec méthodes Process destroy() exitValue() getInputStream() getOutputStream() getErrorStream()

I/O packagePOO-L3 H. Fauconnier91 Exemple exécuter une commande (du système local) associer l'entrée de la commande sur System.in associer la sortie sur System.out.

I/O packagePOO-L3 H. Fauconnier92 Exemple class plugTogether extends Thread { InputStream from; OutputStream to; plugTogether(OutputStream to, InputStream from ) { this.from = from; this.to = to; } public void run() { byte b; try { while ((b= (byte) from.read()) != -1) to.write(b); } catch (IOException e) { System.out.println(e); } finally { try { to.close(); from.close(); } catch (IOException e) { System.out.println(e); }

I/O packagePOO-L3 H. Fauconnier93 Exemple suite public class Main { public static Process userProg(String cmd) throws IOException { Process proc = Runtime.getRuntime().exec(cmd); Thread thread1 = new plugTogether(proc.getOutputStream(), System.in); Thread thread2 = new plugTogether(System.out, proc.getInputStream()); Thread thread3 = new plugTogether(System.err, proc.getErrorStream()); thread1.start(); thread2.start(); thread3.start(); try {proc.waitFor();} catch (InterruptedException e) {} return proc; } public static void main(String args[]) throws IOException { String cmd = args[0]; System.out.println("Execution de: "+cmd); Process proc = userProg(cmd); }