I21 Algorithmique et programmation II David Gross-Amblard, Joël Savelli IEM-uB GFDL 1.2 CM2 version 2
i IEM / uB GFDL 1.22 Plan du cours I.Rappels sur Java - types, instructions, procédures, fonctions... II.Programmation par objet - classe, composition, héritage, initiation à la modélisation III.Algorithmes (et types de données) – algorithmes de tri, algorithmes récursifs, listes, piles, files, arbres
i IEM / uB GFDL 1.23 Procédure public static void afficheNom(String nom){ System.out.println(« Le nom est »+nom); } ● void : c'est une procédure, l'appel est une instruction (n'a pas de valeur)
i IEM / uB GFDL 1.24 Fonctions public static int annéeNaissanceApprox(int age){ return 2009-age; } ● int : type de retour ● Appel : possède une valeur (l'appel est une expression) ● ex. System.out.println(anneeNaissanceApprox(35)); ● return : instruction terminale, fixant la valeur de retour
i IEM / uB GFDL 1.25 return ● Peut apparaître plusieurs fois public static int f(int x){ if (x>0) return 10; if (x>10) return 0; // else implicite return 20; // else implicite }
i IEM / uB GFDL 1.26 Type de retour possible : tous public static String friseDe5(String motif){ return motif+motif+motif+motif+motif; } String dessin=friseDe5(''*''); (valeur de dessin : ''*****'') ● Rappel : +, opérateur de concaténation de chaînes
i IEM / uB GFDL 1.27 Résumé ● Procédures : instructions, pas de valeur ● Fonctions : expressions, ont une valeur ● Distinction entre les deux : faux type de retour void pour procédures ● (comme en C, C++, à la différence du Pascal)
i IEM / uB GFDL 1.28 Syntaxe class MonProgramme { public static int maFonction(int x){...} public static void maProcédure(){...} public static void main(String[] arg){...} } ● main est une procédure ● java MonProgramme exécute la procédure main de MonProgramme.java (.class) ● java MonProgramme salut bonjour, idem, avec arg[0]=''salut'', etc.
i IEM / uB GFDL 1.29 Curiosité ● En Java (comme en C, C++), on peut – oublier la valeur de retour d'une fonction – donc, la considérer comme une instruction anneeNaissanceApprox(35); ● (résultat perdu) ● Par contre, une procédure n'a jamais de valeur int x=afficheNom(''toto''); // erreur ● Pas de déclaration de variable void (pas un type)
i IEM / uB GFDL Bonne pratique ● Fonction utilisée comme instruction : peu élégant ● Séparation stricte : – Fonction : ont une valeur, utilisées dans les expressions, ne font pas d'action (pas d'affichage, modification mémoire,...) – Procédure : n'ont pas de valeur, utilisées comme instructions, font des actions
i IEM / uB GFDL (Autre curiosité en passant ● Affectation (instruction) a aussi une valeur ● Instruction x=3 a pour valeur 3 ● Danger : boolean b=false,c=true; If (b==c)...// valide, condition à faux If (b=c)...// valide, condition à vrai, b modifié)
i IEM / uB GFDL (Autre curiosité en passant ● Opérateur de postincrémentation – x++ a pour valeur x, puis incrémentation x ● Opérateur de préincrémentation – ++x a pour valeur x+1, puis incrémentation de x ● Idem x--, --x for(int x=0;x--<0;x=x++) System.out.println(''génial''); ?)
i IEM / uB GFDL Surcharge des procédures/fonctions ● Autorise plusieurs procédures ou fonctions de même nom ● Différenciées par leur paramètres formels ● ex. la procédure println est surchargée ● println(''toto''); ● println(12); ● Bien sûr, ne surcharger que pour effectuer la même famille d'action
i IEM / uB GFDL Appels imbriqués ● Si une procédure/fonction en appelle une autre ?
i IEM / uB GFDL Pile des appels ● Ex. pour procédures ● Contexte de l'appel : ensemble des variables accessibles avant l'appel ● Appel de la procédure : nouveau contexte, contenant paramètres formels et variables locales de la procédure ● Si procédure appelle autre procédure, empilement d'un nouveau contexte ● Retour : dépilement de contexte
i IEM / uB GFDL Pile des appels p.s. void a(int x, int y){ b(x,x); c(y); } p.s. void b(int x,int z){ c(x);c(z); } p.s. void c(int y){sopln(y);} ● Appel a(5,6) affiche – Appel B(5,5) ● Appel C(5);5 – Appel C(6)6 (p.s. : public static)
i IEM / uB GFDL (Récursivité ● Une définition de procédure/fonction M est récursive si cette définition contient in fine des appels à M. ● (appel direct, ou à une procédure/fonction qui fait appel, ou...) ● Programmation parfois très élégante ● Pour plus tard)
i IEM / uB GFDL Plan du cours I.Rappels sur Java - types, instructions, procédures, fonctions... II.Programmation par objet - classe, composition, héritage, initiation à la modélisation III.Algorithmes (et types de données) - algorithmes de tri, algorithmes récursifs, listes, piles, files, arbres
i IEM / uB GFDL II. Programmation par objet 1. Motivation 2. Encapsulation 3. Héritage 4. Initiation à la modélisation
i IEM / uB GFDL Vers l'abstraction et au delà ● Représentation machine : (concret) ● Représentation Java : int 72 (abstraction) ● Représentation d'un étudiant avec types de base – String nom, String prenom, int anneeNaissance ● Bien, mais peut-on aller plus loin ?
i IEM / uB GFDL Avec types de base ● Savoir si deux étudiants sont potentiellement la même personne p.s. boolean mêmePersonne(String nom1, String prenom1, int annee1, String nom2, String prenom2, int annee2){ if (nom1.equals(nom2) && (prenom1.equals(prenom2) && annee1==annee2) return true; return false; }
i IEM / uB GFDL Limitation ● Pénible (nombre de paramètres formels) ● Difficile à mettre à jour – Si il faut ajouter numéro de sécurité social ? – Changer partout la représentation concrète de l'étudiant – Ajouter des paramètres à la fonction précédente – Modifier son code pour comparer numéro de sécu. ● Objectif : faire de Etudiant un type à part entière
i IEM / uB GFDL Programmation par objets ● Evolution des langages de programmation : nouvelle notion de type ● Langage impératif objet : Java, Pascal, C++ ● (Langage fonctionnel objet : ocaml ● Langage logique objet : oopl) ● Pas d'objets : C
i IEM / uB GFDL Principes ● Encapsulation : rassembler en un nouveau type la représentation et les traitements d'une notion abstraite – ex. : notion d'étudiant : type Etudiant ● Héritage : matérialiser la relation d'héritage (des représentations, des traitements) entre les notions abstraites – ex. : un etudiant est une personne – le type Etudiant hérite (quoi) du type Personne
Déclaration Instanciation Constructions Accès aux membres et droits d'accès Destruction d'instances Membres de classe 2. Encapsulation
Encapsulation ● Regroupement des propriétés et des traitements dans une même « capsule » ● Nouveau type : classe ● La classe définit ses membres : ● Attributs : propriétés (variables et constantes) ● Méthodes : traitements (procédures ou fonctions)
class Etudiant Membres : { String nom, prenom;Attributs int dateNaissance; String numeroEtudiant; int[] notes; String academie,ufr,formation; double valeurMoyenne(){…}Methodes String valeurMention(){…} void fixeMoyenne(float note){…} void editeDiplome(){…} void editeCarte(){…} } Modèle d’un étudiant (scolarité)
Règle et conventions Java ● Règle : – Un fichier par définition de classe, ayant le même nom que la classe – ex. Etudiant.java pour classe Etudiant ● Convention : – Identificateur de classe débute par une majuscule – Identificateur d'attribut, méthode : par une minuscule
Instanciation ● ex : – 3 : instance du type (de base) int – l'étudiant John Doe est une instance de la classe Etudiant ● Instanciation : matérialisation en mémoire d'un objet respectant la définition de sa classe (l'objet a les attributs et méthodes spécifiés) ● Objet : instance d'une classe ● Type d'un objet : sa classe ● Une classe peut avoir plusieurs instances
Instanciation d'une classe Etudiant e; e=new Etudiant(); ● Objets toujours manipulés par référence (e est une référence vers l'objet de type Etudiant) ● Deux étapes : – Allocation mémoire de chaque attribut – Initialisation : appel de la méthode constructeur
Constructeur(s) ● Méthode(s) ayant pour identificateur le nom de la classe et pas de type de retour Class Etudiant { String nom; public Etudiant(){nom=''inconnu''}; public Etudiant(String n){nom=n;} public Etudiant(Etudiant e){... } } ● Surcharge des constructeurs
Utilisation des constructeurs Etudiant e=new Etudiant(); Etudiant e2=new Etudiant(« Bob »); Etudiant e3=new Etudiant(e2); ● Si aucun constructeur défini : constructeur par défaut Etudiant() (donne leur valeur par défaut aux attributs)
Accès aux membres ● Méthodes d'un objet : accès direct à ses propres attributs Class Etudiant { String nom; public void fixeNom(String n){ nom=n; }
Accès aux membres ● De l'extérieur : notation pointée Etudiant e=new Etudiant(« bob »); System.out.println(e.nom); e.fixeNom(''john'');
Danger ● Le code externe à l'objet peut manipuler directement son état interne e.Moyenne=-15; // Moyenne négative ? e.nom=null; // N'y a-t-il pas toujours un nom ? ● Peu souhaitable
Droits d'accès sur les membres ● Mots-clés public, private ● Membre public : toujours accessible ● Membre private : accessible uniquement depuis les méthodes de la classe ● (existe d'autres subtilités)
Exemple Class Etudiant { public String nom; private String codeSecret; public void afficheNom(){...} private int calculAge(){...} } Etudiant e=new Etudiant(); e.nom=''bob''; //ok e.codeSecret=''truc''; // interdit e.afficheNom(); // ok int n=e.calculAge(); // interdit
Destruction d'instances Etudiant e=new Etudiant(); e=new Etudiant(); ● Premier objet perdu ● Si un objet n'est plus référencé par aucune variable, alors (a un moment donné), il est effacé de la mémoire et la mémoire réutilisée ● Mécanisme de ramasse-miette (glanage de cellule, garbage collecting) ● (Idem pour les tableaux et les chaînes)