I21 Algorithmique et programmation II David Gross-Amblard, Joël Savelli IEM-uB 2008-2009 - GFDL 1.2 CM 5/8 v2
II. Programmation par objet 1. Motivation 2. Encapsulation 3. Héritage 4. Initiation à la modélisation i21 IEM-UB 2008-2009 GFDL 1.2 2
Remarques Toute classe hérite (implicitement) de la classe Object class Object { public String tostring(){ // par défaut, affiche adresse mémoire public boolean equals(object O){ // par défaut, compare les adresses mémoires i21 IEM-UB 2008-2009 GFDL 1.2 3
II. Programmation par objet 1. Motivation 2. Encapsulation 3. Héritage 4. Initiation à la modélisation i21 IEM-UB 2008-2009 GFDL 1.2 4
Modélisation Objectif : passer du problème au code Nombreuses méthodologies MERISE (Tardieu et al., 1983) - RACINES - NIAM - OMT (Object Modeling Technique) - Booch- OOSE- SADT -SART SA/SD MACAO -FAST- APTE Unified Process / UML IDM -... i21 IEM-UB 2008-2009 GFDL 1.2 5
Démarche simplifiée Étant donné un problème posé (expression des besoins, ex. votre projet) 1.Formaliser ces besoins : cahier des charges 2.Identifier : Les concepts importants : classes leurs opérations : méthodes 3.Identifier les relations entre classes : composition/héritage i21 IEM-UB 2008-2009 GFDL 1.2 6
Exemple : Université Expression des besoins «Votre programme doit permettre de saisir des étudiants et des enseignants, de désigner un jury de 3 personnes,composé de 2 enseignants et un étudiant. Un enseignant a un bureau. Un étudiant possède des notes. Chaque personne a un nom, un prénom et une date de naissance» i21 IEM-UB 2008-2009 GFDL 1.2 7
1. Cahier des charges Données Opérations Personne Mise à jour Etudiant Mise à jour Enseignant Mise à jour Etudiants Ajout / suppression Enseignants Ajout / suppression Jury Constitution i21 IEM-UB 2008-2009 GFDL 1.2 8
2. Classes et méthodes Personne Etudiant Enseignant Jury nom nom nom Etudiant prénom prénom prénom Ens1 date naissance date naissance date naissance Ens2 notes bureau parties communes : suggère une superclasse commune i21 IEM-UB 2008-2009 GFDL 1.2 9
3. Relations entre classes Identifier les 2 relations suivantes : composition : est-composé-de héritage : est-une-sorte-de ex. Etudiant est-une-sorte-de Personne ex. Jury est-constitué-de Etudiant ex. Jury est-constitué-de Enseignant i21 IEM-UB 2008-2009 GFDL 1.2 10
est-une-sorte-de / est-composé-de A est-une-sorte-de B : relation d'héritage A hérite de B class A extends B A est-composé-de B : relation de composition A possède un attribut de type B (ou B[] si plusieurs) class A { B b; // ou B[] b si plusieurs i21 IEM-UB 2008-2009 GFDL 1.2 11
Outils de réflexion et communication Aspects statiques du programme Diagramme d'héritage Diagramme de composition Aspects dynamiques Diagramme des traitements i21 IEM-UB 2008-2009 GFDL 1.2 12
Outil 1 : diagramme d'héritage Personne Jury Etudiant Enseignant : relation d'héritage i21 IEM-UB 2008-2009 GFDL 1.2 13
outil 2 : diagramme de composition Jury Enseignant Etudiant : relation de composition i21 IEM-UB 2008-2009 GFDL 1.2 14
Méthodes Principe de délégation (subsidiarité) Un objet composite (groupe d objets) doit déléguer à ses composants tout ce qu ils peuvent faire seuls Il doit conserver toutes les propriétés et les méthodes qui concernent plusieurs de ses composants i21 IEM-UB 2008-2009 GFDL 1.2 15
Principe de délégation class Jury { Enseignant ens1,ens2; Etudiant etu; public void affiche(){ System.out.println("Constitution du jury :"); System.out.println(etu.getNom()+''+etu.getPrenom()); System.out.println(ens1.getNom(+''+ens1.getPrenom()); System.out.println(ens2.getNom(+''+ens2.getPrenom()); i21 IEM-UB 2008-2009 GFDL 1.2 16
Principe de délégation class Jury { Enseignant ens1,ens2; Etudiant etu; public void affiche(){ System.out.println("Constitution du jury :"); etu.affiche(); ens1.affiche(); ens2.affiche(); Mieux : Etudiant, Enseignant fournissent leur propre affichage i21 IEM-UB 2008-2009 GFDL 1.2 17
Outil 3 : diagramme des traitements événement ou donnée événement ou donnée traitement cas 1 cas2 événement ou donnée i21 IEM-UB 2008-2009 GFDL 1.2 18
Outil 3 : diagramme des traitements saisie info. étudiant validation saisie invalide valide objet Etudiant Interface graphique stockage (Etudiants) boite de dialogue d'erreur i21 IEM-UB 2008-2009 GFDL 1.2 19
II. Programmation par objet 1. Motivation 2. Encapsulation 3. Héritage 4. Initiation à la modélisation i21 IEM-UB 2008-2009 GFDL 1.2 20
Plan du cours I. Rappels sur Java - types, instructions, procédures, fonctions... I. Programmation par objet - classe, composition, héritage, initiation à la modélisation Bonus I. Types de données et algorithmes - listes, piles, files, arbres, algorithmes de tri, algorithmes récursifs i21 IEM-UB 2008-2009 GFDL 1.2 21
Bonus 1. Modularité en Java 2. Mécanisme des exceptions i21 IEM-UB 2008-2009 GFDL 1.2 22
Modularité en Java Premier niveau : classe rassemble dans un type sa représentation (attributs) et ses traitements (méthodes) droits d'accès : gestion de la visibilité (seul le concepteur de la classe connais les détails internes) Second niveau : bibliothèques (packages) rassemble les classes traitant d'un même thème (ex. tout ce qui est graphique / tout ce qui est Université...) logiciel industriel : plusieurs centaines de classes i21 IEM-UB 2008-2009 GFDL 1.2 23
Bibliothèques Pour être dans une même bibliothèque Universite, un ensemble de fichiers de classe : doivent se trouver dans un même répertoire Universite doivent commencer par package Universite; Classes sans indication de bibliothèque : bibliothèque par défaut (default package) i21 IEM-UB 2008-2009 GFDL 1.2 24
Utilisation de bibliothèque Clause import import javax.swing.jframe; // classe JFrame, fenêtre graphique import javax.swing.*; // toutes les classes graphiques Par défaut : java.lang.* (permet d'utiliser System, Math, String par exemple) i21 IEM-UB 2008-2009 GFDL 1.2 25
Bibliothèques : visibilité package Universite; public class Etudiant {... private class Enseignant {... Les classes d'une même bibliothèque se voient entre elles les classes publiques : visibles par les classes extérieures après import les classes private sont invisibles (cachent un détail d'implémentation, inutile pour les autres programmeurs) i21 IEM-UB 2008-2009 GFDL 1.2 26
Premier programme enfin clair package tp2; import java.lang.*; public class toto { public static void main(string arg[]){ int x=lire.d(); // il faut package tp2; au début de // Lire.java System.out.println(Math.floor(12.2));... i21 IEM-UB 2008-2009 GFDL 1.2 27
Bonus 1. Modularité en Java 2. Mécanisme des exceptions i21 IEM-UB 2008-2009 GFDL 1.2 28
Les exceptions Ex. trouver l'indice de la première occurrence d'un entier dans un tableau public int indice(int recherche,int[] tab){ for(int i=0 ; i<tab.length ; i++) if (tab[i]==recherche) return i; return -1; i21 IEM-UB 2008-2009 GFDL 1.2 29
Motivation -1 : valeur spéciale Utilisation if (indice(3,tableau)==-1) Sopln(«Pas trouvé»); else position=indice(3,tableau)+2; Mauvaise utilisation : position=indice(3,tableau)+2; Risque d'erreur, pas détecté à la compilation i21 IEM-UB 2008-2009 GFDL 1.2 30
Les exceptions Mécanisme permettant à une méthode de signaler à la méthode appelante qu'un événement exceptionnel est survenu à la méthode appelante de détecter les événements exceptionnels et d'y réagir selon leur type Exception : instance de la classe Exception Indication : clause throws Signaler : instruction throw Adapter : bloc try / catch / finally i21 IEM-UB 2008-2009 GFDL 1.2 31
Utilisation public int indice(int rech,int[] tab) throws Exception { for(int i=0;i<tab.length;i++) if (tab[i]==rech) return i; throw new Exception(); i21 IEM-UB 2008-2009 GFDL 1.2 32
Utilisation par l'appelant try { position=indice(3,tableau)+2; catch (Exception e){ System.out.println(«Pas trouvé»); e.printstacktrace(); // affiche l'origine du problème Utiliser indice sans bloc try/catch filtrant le type Exception est invalide (erreur à la compilation) catch n'interrompt pas l'exécution i21 IEM-UB 2008-2009 GFDL 1.2 33
Définir ses propres exceptions Hériter de Exception class PasTrouve extends Exception { Utilisation public int indice(int recherche,int[] tab) throws PasTrouve{ for(int i=0;i<tab.length;i++) if (tab[i]==recherche) return i; throw new PasTrouve(); i21 IEM-UB 2008-2009 GFDL 1.2 34
Utilisation par l'appellant try { position=indice(3,tableau)+2; catch (PasTrouve e){ System.out.println(«Pas trouvé»); e.printstacktrace(); i21 IEM-UB 2008-2009 GFDL 1.2 35
Exceptions prédéfinies IOException : erreur d'entrée-sortie (fichier,...) ArrayIndexOutOfBoundsException : erreur d'indice dans un tableau NullPointerException : accès aux éléments d'un tableau ou aux membres d'un objet dont la référence est à null (voir aussi Lire.java) i21 IEM-UB 2008-2009 GFDL 1.2 36
Filtrage des différentes exceptions try {... catch (IOException e){ // traitement de l'ioexception catch(nullpointerexception e2){ // traitement du NullPointerException i21 IEM-UB 2008-2009 GFDL 1.2 37
Transmission des exceptions à l'appelant class E1 extends Exception { class E2 extends Exception { appel void d() throws E1,E2 appel void c() throws E1,E2 appel void méthode b() throws E2 méthode a() i21 IEM-UB 2008-2009 GFDL 1.2 38
Transmission des exceptions à l'appelant class E1 extends Exception { class E2 extends Exception { appel void d() throws E1,E2 throw E1 appel void c() throws E2 catch E1 {... appel void méthode b() throws E2 méthode a() i21 IEM-UB 2008-2009 GFDL 1.2 39
Transmission des exceptions à l'appelant class E1 extends Exception { class E2 extends Exception { appel void d() throws E1,E2 throw E2 appel void c() throws E2 transmission E2 catch E1 {... appel void méthode b() catch E2 {... méthode a() i21 IEM-UB 2008-2009 GFDL 1.2 40
Transmission des exceptions à l'appelant class E1 extends Exception { class E2 extends Exception { appel void d() throws E1,E2 throw NullPointerException appel void c() throws E2 transmission NullPointerException catch E1 {... appel méthode main() void méthode b() catch E2 {... transmission NullPointerException transmission NullPointerException : arrêt du programme i21 IEM-UB 2008-2009 GFDL 1.2 41
Programme stable class Main { public static void main(string arg[]){ try { lasuite(); catch (Throwable e){ Sopln(«un problème est survenu : contactez votre revendeur»); sauvegarde(); i21 IEM-UB 2008-2009 GFDL 1.2 42
Clause finally try {... catch (type1 e1){... catch(type2 e2){... finally { // exécuté dans tous les cas, même si aucune exception levée i21 IEM-UB 2008-2009 GFDL 1.2 43
Plan du cours I. Rappels sur Java - types, instructions, procédures, fonctions... I. Programmation par objet - classe, composition, héritage, initiation à la modélisation Bonus I. Types de données et algorithmes - listes, piles, files, arbres, algorithmes de tri, algorithmes récursifs i21 IEM-UB 2008-2009 GFDL 1.2 44
Types de données et algorithmes 1.Récursivité 2.Algorithmes de tri 3.Types de données i21 IEM-UB 2008-2009 GFDL 1.2 45
Récursivité Déclaration récursive : la déclaration d'un notion est dite récursive si cette déclaration contient la notion elle-même Notion : procédure, fonction, type,... i21 IEM-UB 2008-2009 GFDL 1.2 46
(Type récursif) Définition : un type est récursif si sa définition contient un attribut de ce type class RameDeMetro { int nbplaceassises; RameDeMetro suitedelarame; (exemples plus tard...) i21 IEM-UB 2008-2009 GFDL 1.2 47
Méthodes récursives Définition : une méthode est récursive si sa déclaration contient (in fine) un appel à la méthode int factorielle(int n){ if (n==0) return 1; else return n*factorielle(n-1); i21 IEM-UB 2008-2009 GFDL 1.2 48
Méthodes récursives Récursivité directe : appel dans la définition de la méthode Récursivité indirecte : appel à la méthode réalisé par une autre méthode appelée dans la définition void f(int i){ if (i>0) g(i-1); void g(int i){ if (i>0) f(i- 1); i21 IEM-UB 2008-2009 GFDL 1.2 49
Terminaison des méthodes récursives Comme toute méthode, l'exécution peut ne pas terminer void f(int i){ if (i==0) return 1; else return 2*f(i+1); f(1) appelle f(2) qui appelle f(3)... i21 IEM-UB 2008-2009 GFDL 1.2 50
Terminaison des méthodes récursives Forme simple : paramètre n, entier positif ou nul embranchement en fonction de n void f(int n){ cas de base (n=0) : pas d'appel récursif cas général (n>0) : appels récursifs, pour paramètre strictement inférieures de n if(n==0) // cas de base if (n>1) // cas général f(n-1) i21 IEM-UB 2008-2009 GFDL 1.2 51
Terminaison Critère de terminaison : Il existe une quantité de contrôle entière et positive qui décroît strictement à chaque appel récursif Termine, car atteint nécessairement 0 (cas de base) (Il n'existe pas de suite infinie strictement décroissante sur les entiers positifs) i21 IEM-UB 2008-2009 GFDL 1.2 52
Terminaison des méthodes récursives Pas toujours si simple... Fonction d'ackermann-péter [1926] int ack(int x,int y){ if (x==0) return 2*x; if (y==0) return 1; return ack(x-1,ack(x,y-1)); Termine toujours Wilhelm Ackermann (1896-1962) i21 IEM-UB 2008-2009 GFDL 1.2 53
Cas particulier : suites définies par récurrence suite définie par récurrence, indice n : (un nombre fini de) cas de bases cas général : défini en fonction de n'<n Ex. factorielle u 0 =1 u n =n*u n-1, pour n>0 i21 IEM-UB 2008-2009 GFDL 1.2 54
Suite par récurrence / fonction récursive Suite par récurrence : u 0 =c 0, u 1 =c 1,...u k =c k u n =f(u n-1,u n-2,...), n>k Fonction récursive correspondante void u(int n){ if (n==0) return c 0... if (n==k) return c k if (n>k) return f(u(n-1),u(n-2),...) i21 IEM-UB 2008-2009 GFDL 1.2 55
Suite par récurrence / fonction récursive Toute suite par récurrence peut être transcrite en une fonction récursive Il existe des fonctions récursives qui n'ont pas de définition par récurrence Fonction d'ackermann (premier exemple 1926, même avec imbrication de suite par récurrence) i21 IEM-UB 2008-2009 GFDL 1.2 56
Programmation récursive Avantages Concision des algorithmes Analyse plus "naturelle" de certains problèmes Inconvénients L'exécution demande plus de place mémoire et plus de temps à cause de la répétition des appels (taille de la pile d'appel) i21 IEM-UB 2008-2009 GFDL 1.2 57
Version itérative Procédure/fonction itérative : sans appel récursif On peut toujours transformer une fonction récursive en une version itérative (méthode générale : simuler la pile des appels) cas simple : fonctions récursives terminales i21 IEM-UB 2008-2009 GFDL 1.2 58
Fonctions récursives terminales Une fonction récursive f est dite récursive terminale si il n'y a aucun traitement à effectuer après chaque appel récursif Autrement dit : chaque appel récursif de la forme return f(..) i21 IEM-UB 2008-2009 GFDL 1.2 59
Exemple : non terminal int factorielle(int n){ if (n>0) return n*factorielle(n-1); else // n==0 return 1; termine toujours, mais non terminale i21 IEM-UB 2008-2009 GFDL 1.2 60
int factorielle(int n){ return fact(n,1); int fact(int n,int a){ if (n<=1) return a; else return fact(n-1,n*a); Exemple : terminal a : accumulateur du résultat i21 IEM-UB 2008-2009 GFDL 1.2 61
De récursif terminal à itératif int fact(int n,int a){ if (n<=1) return a; else return fact(n-1,n*a); int factiteratif(int n, int a){ while(n>1){ a=n*a; n=n-1; return a; i21 IEM-UB 2008-2009 GFDL 1.2 62
Schéma général fonction f(x){ if (C(x)){ I1(x); return f(t(x)); else { I2(x); return R(x); int f(int x){ while (C(x)){ I1(x); x=t(x); I2(x); return R(x); i21 IEM-UB 2008-2009 GFDL 1.2 63
Intérêt Pas de pile d'appel : moins de mémoire Certains compilateurs : détection automatique du récursif terminal Récriture automatique du code en conséquence i21 IEM-UB 2008-2009 GFDL 1.2 64