1 / 68

Introduction

Introduction. Approche fonctionnelle Approche objet JAVA. Approche fonctionnelle. Transformer un nombre (NB). Valide (NB). Orthographier-C(NB). Orthographier-F(NB). Orthographier-3 (N). Orthographier-D(N). Orthographier-U (N).

biana
Télécharger la présentation

Introduction

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction Approche fonctionnelle Approche objet JAVA

  2. Approche fonctionnelle Transformer un nombre (NB) Valide (NB) Orthographier-C(NB) Orthographier-F(NB) Orthographier-3 (N) Orthographier-D(N) Orthographier-U (N) PB : transformer un nombre numérique en son équivalent alphanumérique

  3. Programmation procédurale Les facilités de base offertes par les langages qui supportent ce style de programmation sont les fonctions qui admettent des arguments et qui renvoient des valeurs. Comme exemple, considérons la fonction qui calcule le pgcd de deux entiers positifs long pgcd(long x, long y) { unsigned long r ; if (x < y) { r = x ; x = y ; y = x ; } do { r = x % y // r est le reste de la division entière de x et y x = y ; y = r } // réitérer ce processus en échangeant (x, y) par (y, r) while (r != 0) ; // tant que le reste de la division entière x et y est non nul return x ; // retourne le pgcd } Une fois cette fonction donnée, il est possible à présent d'utiliser cette fonction dans toute autre fonction. void une_fonction(void) { ... x = pgcd(4356, y) ; ... }

  4. Programmation modulaire (1) Avec l'augmentation de la taille des programmes, la programmation procédurale atteint ses limites ; la programmation modulaire voit alors le jour. Ce style de programmation utilise les principes d'encapsulation des données. L'ensemble des procédures ou fonctions dépendantes et les données qu'elles manipulent sont regroupés dans un module. Un programme est alors constitué de plusieurs modules et la communication inter-modules se fait à travers une interface ; les détails d'implantation de chaque module sont cachés aux autres modules. Imaginons qu'il faille réaliser un programme dans lequel on utilise des piles. Un des modules de ce programme se charge de l'implantation d'une pile et les détails de cette implantation devant être ignorés par les autres modules. L'interface que fournit ce module est constituée d'un fichier (par exemple " pile.h ") // Interface du module PILE de caractères (pile.h) void empiler(char) ; char depiler(void) ; // Fin de l'interface

  5. Programmation modulaire (2) Les utilisateurs de ce module ignorent parfaitement les détails d'implantation de cette pile. En particulier, s'agit-il d'un tableau ou d'une liste chaînée ? Seul le programmeur de ce module le sait. L'utilisation de ce module par d'autres se fait alors de la manière suivante : // Module XXX utilisant une pile de caractère #include "pile.h" void une_fonction() { short c1, c2 ; ... empiler('a') ; empiler('b') ; ... c1 = depiler() ; if (c1 == ERREUR) erreur(" la pile est vide ") ; c2 = depiler() ; if (c2 == ERREUR) erreur(" la pile est vide ") ; ... } // Fin du module XXX

  6. Programmation modulaire (3) Cette première tentative de modularité ne permet l'utilisation que d'une seule pile. Il est souvent nécessaire de disposer de plusieurs piles dans un même programme. La solution consiste à fournir une interface plus sophistiquée dans laquelle un nouveau type de donnée appelé id_de_pile sera défini. // Interface du module PILE de caractères typedef ... id_de_pile ; id_de_pile creer_pile ( ) ; void empiler (id_de_pile, char) ; char depiler (id_de_pile) ; void detruire_pile (id_de_pile) ; // Fin de l'interface

  7. Programmation modulaire (4) Idéalement, on aurait souhaiter que le type abstrait id_de_pile se comporte comme un type prédéfini. Or, cela n'est pas le cas : il appartient à l'utilisateur de ce module de s'assurer de la bonne utilisation. En particulier, celui-ci devra allouer les variables nécessaires pour manipuler ces piles, s'assurer qu'elles sont désallouées. // Module XXX utilisant une pile de caractère #include "pile.h" void une_fonction(void) { id_de_pile p1, p2 ; char c1, c2 ; ... p1 = creer_pile() ; // p2 non créée empiler(p1, 'a') ; c1 = depiler(p1) ; if (c1 == EOF) erreur(" la pile est vide ") ; detruire_pile(p2) ; p1 = p2 ; // p2 utilisée après sa destruction ; p1 non détruit ... } // Fin du module XXX

  8. Flexibilité (1) Une fois un type de donnée défini, il interfère très peu avec le reste du programme ; pourtant toute modification ou enrichissement de ce type de donnée entraîne une refonte complète du programme. Imaginons que l'on définit un type de donnée forme. typedef enum {cercle, triangle, carree} type ; typedef struct forme { point centre ; type t ; } forme ; Le programmeur devra connaître toutes les formes manipulées pour implanter la fonction dessiner : void dessiner(forme f) { switch(t.type) { case cercle : ... break ; case triangle : ... break ; case carree : ... break ; } }

  9. Flexibilité (2) La suppression d'une forme ou l'ajout d'une nouvelle forme force le programmeur à reprendre l'ensemble des fonctions et à les adapter. Le mécanisme d'héritage de la programmation objet apporte une solution élégante au problème soulevé précédemment. On définit tout d'abord une classe qui possède les propriétés générales de toutes les formes : class forme { private point centre ; ... public point position() { return center ; } public void deplacer(point vers) { center = vers ; dessiner() ; } public abstract void dessiner() ; public abstract void tourner(int) ; ... }

  10. Flexibilité (3) Les fonctions dont l'implantation (ou la mise en oeuvre) est spécifique pour chaque forme sont marquées par le mot clé abstract. Pour définir effectivement ces fonctions, on commencera par définir une classe dérivée de la classe forme : class cercle extends forme { private int rayon ; public void dessiner() { ... } public void tourner(int) { } }

  11. Abstraction de données(1) Le support pour la programmation par abstraction de données consiste à fournir des facilités pour définir des opérations pour un type défini par l'utilisateur. Contrairement aux types prédéfinis, aucun système ne peut définir, par défaut, les fonctions d'initialisation et de destruction des types définis par le programmeur ; il lui appartient donc de fournir ces fonctions. Considérons un type nouvellement défini (que l'on appellera tableau) qui est constitué de sa taille et d'un pointeur vers les éléments du tableau. La création d'un objet de type tableau se fait en définissant une variable de la classe tableau. Que doit-on créer à l'initialisation ? Faut-il allouer la place nécessaire pour coder le tableau ? etc. Les réponses à ces questions ne peuvent être fournies que par l'utilisateur ayant défini le type tableau. Une première solution consiste à se définir une fonction init que l'utilisateur se forcera à appeler avant toute utilisation d'un objet d'un type utilisateur.

  12. Abstraction de données(2) class tableau { private int [] t ; public void init(int taille) ; ... } ; void une_fonction() { tableau t ; ... t.init(2) ; // n'utiliser t qu'après son initialisation } Cette solution est peu agréable et la programmation orientée objet fournit un mécanisme plus astucieux nomme constructeur . Par contre, contrairement aux langages de programmation objet habituels, il n'est pas nécessaire de fournir un destructeur pour les objets d'un type défini par l'utilisateur. Cette destruction se fera automatiquement et une récupération mémoire se charge de restituer au système la place mémoire rendue libre. class tableau { private int [] t ; tableau(int s) { if (s<=0) erreur(...) ; t = new int[n] ; } ; }

  13. La programmation orientée objetLes objets (1) • La POO est fondée sur le concept d ’objets, à savoir une association des données et des procédures (appelées méthodes) agissant sur ces données; Méthodes + Données = Objets • Cette association est plus qu ’une simple juxtaposition ! POO « pure » = encapsulation des données. --> Il n ’est pas possible d ’agire directement sur les données d ’un objet; il est nécessaire de passer par l ’intermédiaire de ses méthodes qui jouent ainsi le rôle d ’interface obligatoire. Vocabulaire : l ’appel d ’une méthode est en fait l ’envoi d ’un message à l ’objet.

  14. La programmation orientée objetLes objets (2) Remarque 1 : du fait de l ’encapsulation, vu de l ’extérieur, un objet se caractérise uniquement par les spécifications de ses méthodes. La manière dont sont réellement implantées les données est sans importance. Remarque 2 : l ’encapsulation des données facilite considérablement la maintenance d ’un logiciel : une modification éventuelle de la structure de données d ’un objet n ’a d ’incidence que sur l ’objet lui-même; les utilisateurs de l ’objet ne seront pas concernés par la teneur de cette modification. De la même manière, l ’encapsulation des données facilite grandement la réutilisation d ’un objet.

  15. La programmation orientée objetLes objets (3) • En POO, le concept de classe correspond à la généralisation de la notion de type rencontré dans les langages classiques • Une classe est la description d ’un ensemble d ’objets ayant une structure de donnée commune et disposant des mêmes méthodes --> Les objets apparaissent alors comme des variables d ’un tel type classe • En POO, on dit qu ’un objet est une instance de sa classe. • Le concept d ’héritage permet de définir une nouvelle classe à partir d ’une classe existante (réutilisée en bloc !), à laquelle on ajoute de nouvelles données et de nouvelles méthodes.

  16. Bref Historique • 1993 : projet Oak (langage pour l’électronique grand public) • 1995 : Java / HotJava • Mai 95 : Netscape prend la licence • Sept 95 : JDK 1.0 b1 • Déc 95 : Microsoft se dit intéressé • Janv 96 : JDK 1.0.1 • Fin 96 : RMI, JDBC, JavaBeans, … • Fév 97 : JDK 1.1 • 1999 : JDK 1.2 (Java 2) • 2000 : JDK 1.3 (Java 2) • 2002 : JDK 1.4 (Java 2)

  17. Qu’est ce que Java ? • Orienté objets • Interprété • Portable • Simple • Robuste • Sécurisé • Multi_threads • Distribué

  18. Java est un langage orienté objets • Tout est classe (pas de fonctions) sauf les types primitifs (int, float, double, …) et les tableaux • Toutes les classes dérivent de java.lang.Object • Héritage simple pour les classes • Héritage multiple pour les interfaces • Les objets se manipulent via les références • La syntaxe est proche de celle de C

  19. Essai.java Programmejava Compilateur JAVA JVM : Java Virtual Machine Programmeen byte code Essai.class Interpréteur 001101001 Java est interprété

  20. Java est portable

  21. Java est robuste • A l’origine, c’est un langage pour les applications embarquées • Gestion de la mémoire par un garbage collector • Pas d’accès direct à la mémoire • Mécanisme d’exception • Accès à une référence null -> exception • Compilateur contraignant (erreur si exception non gérée, si utilisation d’une variable non affectée, …). • Tableaux = objets (taille connue, débordement -> exception). • Seules les conversions sûres sont automatiques • Contrôle des cast à l’exécution

  22. Java est sécurisé • Indispensable avec le code mobile • Pris en charge dans l’interpréteur • Trois couches de sécurité : - Vérifier le byte code - Class loader : responsable du chargement des classes - Security Manager : accès aux ressources • Code certifié par une clé

  23. Java est multi-thread • Intégrés au langage et aux API : • Synchronized • Garbage collector dans un thread de basse priorité • Java.lang.Thread, java.lang.Runnable • Accès concurrents à objets gérés par un monitor • Implémentation propre à chaque JVM • Difficultés pour la mise au point et le portage

  24. Java est distribué • API réseau (java.net.Socket, java.net.URL, …). • Applet • Servlet • JavaIDL (CORBA) • JSP • RMI

  25. Compilateur Java Virtual Machine API de Java Système d’exploitation Le JDKJava Development Kit • Javac : compilateur de sources java • Java : interpréteur de byte code • Appletviewer : interpréteur d’applet • Javadoc : générateur de documentation

  26. Les principales API Java • Les notions essentielles de Java : • Java.lang : Types de bases, Threads, classLoader, Exception, Math, … • Java.util : Hashtable, vector, Date, … • Java.io : accès aux entrées/sorties • Réseaux : • Java.net : Socket, URL,… • Java.rmi : Remote Method Invocation • Java.idl : interopérabilité avec CORBA • Applets : • java.applet : un ensemble de conventions pour le Web. • Java Database Connectivity (JDBC) : • Java.sql : accèx homogène aux bases de données • Java Beans : • Java.beans : composants logiciels • Graphique : Interface graphique portable AWT et Swing

  27. Site de Sun http://java.sun.com

  28. Premier programme Java Création d’une classe accessible par un autre module public class PremProg { public static void main (String args[]) {System.out.println ("  Mon premier programme Java  "); } } 1ère méthode appelée lors de l’exécution d’un programme JAVA Affichage à l’écran Méthode de classe

  29. Structure générale du programme • Le programme ne comporte qu’une seule classe : PremProg • Cette classe ne comporte qu’une seule méthode : main. • La méthode main indique à l’interpréteur où débuter l’exécution du programme. • Le fichier doit posséder le même nom que la classe. • La méthode main est une méthode de classe. • Le paramètre String[] args permet de récupérer des arguments transmis au programme au moment de son lancement. • Le mot clé public dans « public class PremProg » sert à définir les droits d’accès des autres classes (en fait de leurs méthodes) à la classe PremProg.

  30. Contenu du programme • Une seule instruction : System.out.println (" Mon premier programme Java "); • System désigne une classe dans laquelle se trouve défini un champ static out, représentant la fenêtre console. • La méthode println est une méthode de la classe dont est issu l’objet out (il s’agit de la classe PrintStream). • Remarque : la convention en Java est : • Chaque nom de classe doit commencer par une majuscule • Chaque nom de méthode et d’objet doit commencer par une minuscule.

  31. Exécution d’un programme Java • Avec le JDK : javac PremProg.java java PremProg Mon premier programme Java • Avec un outil RAD (Eclipse, Jbuilder, …), une fenêtre console sera générée dans laquelle sera affiché le résultat d’exécution du programme. Génération du fichier PremProg.class Interprétation du fichier PremProg.class Affichage à l’écran

  32. Interface console ou interface graphique (1) • Avec une interface console, c’est le programme qui décide de l’enchaînement des opérations.

  33. Interface console ou interface graphique (2) Dans les programmes à interface graphique (G.U.I), la communication avec l’utilisateur se fait par l’intermédiaire de composants tels que les menus déroulants, les boîtes de dialogues, etc… L’utilisateur a l’impression de piloter le programme  programmation évènementielle. Remarque : comme l’étude de la programmation évènementielle ne se fera pas tout de suite, nous utiliserons les méthodes de la classe Clavier afin de demander des informations à l’utilisateur.

  34. La classe Clavier (1)méthode lireString // classe fournissant des fonctions de lecture au clavier import java.io.*; public class Clavier { public static String lireString () // lecture d’une chaine { String ligne_lue = null; try { InputStreamReader lecteur = new InputStreamReader (System.in); BufferedReader entree = new BufferedReader (lecteur); ligne_lue = entree.readLine(); } catch (IOException err) { System.exit(0);} return ligne_lue; }

  35. La classe Clavier (2)méthode lireFloat public static float lireFloat () // lecture d’un float { float x=0; // valeur à lire try { String ligne_lue = lireString(); x = Float.parseFloat (ligne_lue); } catch (NumberFormatException err) { System.out.println " **** Erreur de donnee *** "); System.exit (0); } return x; }

  36. La classe Clavier (3)méthode lireDouble public static float lireDouble() // lecture d’un double { double x=0; // valeur à lire try { String ligne_lue = lireString(); x = Double.parseDouble (ligne_lue); } catch (NumberFormatException err) { System.out.println " **** Erreur de donnee *** "); System.exit (0); } return x; }

  37. La classe Clavier (4)méthode lireInt public static float lireInt() // lecture d’un int { int n = 0; // valeur à lire try { String ligne_lue = lireString(); n = Integer.parseInt (ligne_lue); } catch (NumberFormatException err) { System.out.println " **** Erreur de donnee *** "); System.exit (0); } return n; } } // fin de la classe Clavier

  38. Exemple d’un petit programme // Calcul de racines carrees public class Racines { public static void main (String[] args) { final int NFOIS = 5; int i; double x; double racx; System.out.println (" Je vais vous calculer " + NFOIS + "racines carrées" ); for (i=0; i<NFOIS ; i++) { System.out.print (" Donnez un nombre : " ); x = Clavier.lireDouble (); if (x<0.0) System.out.println ( x + "  ne possede pas de racine carree "); else { racx = Math.sqrt(x); System.out.println (x + "  a pour racine carree : " + racx); } } } }

  39. Structure du langageLes types primitifs • boolean(true/false), byte (1 octet), char (2 octets), short (2 octets), int (4 octets), • long (8 octets), float (4 octets), double (8 octets). • Les variables peuvent être déclarées n'importe où dans un bloc. • Les affectations non implicites doivent être castées (sinon erreur à la compilation). • int i = 258; • long l = i; // ok • byte b = i; // error: Explicit cast needed to convert int to byte • byte b = 258; // error: Explicit cast needed to convert int to byte • byte b = (byte)i; // ok mais b = 2 • Il existe des constantes prédéfinies : • {Integer ,Byte, Short, Long}.MIN_VALUE , • {Integer ,Byte, Short, Long}. MAX_VALUE

  40. final int n = 20; n = n + 5; // erreur : n a été déclarée final n = Clavier.lireInt (); // Idem final int n; // OK, même si n n’a pas (encore) reçu de valeur … n = Clavier.lireInt (); // première affectation de n : OK … n++; // nouvelle affectation de n : erreur de compilation final int n; … if (…) n = 10; // OK else n = 20 ; Structure du langageLe mot clé final

  41. Structure du langageOpérateurs arithmétiques et logiques Arithmétiques Logiques < <= == > >= != && || ^^ | & 2 opérandes + - * / % & | ^ >> << >>> - ~ 1 opérande ! ? : 3opérandes && || Évaluation gauche-droite par nécessité Faux <-> = 0 Vrai <-> != 0

  42. Structure du langageLes structures de contrôles • Blocs d’instructions : {…} • Instructions : if, switch, do … while, while, for • Instructions de branchement inconditionnel : break et continue avec ou sans étiquettes • UN: while(...) { • DEUX: for(...) { • TROIS: while(...) { • if (...) continue UN; // Reprend sur la première boucle while • if (...) break DEUX; // Quitte la boucle for • continue; // Reprend sur la deuxieme boucle while • } • } • }

  43. Les classes et les objetsLes unités de compilation • Le code source d’une classe est appelé unité de compilation • Il est recommandé (mais pas imposé) de ne mettre qu’une classe par unité de compilation • L’unité de compilation (le fichier) doit avoir le même nom que la classe qu’elle contient. • Si un fichier contient plusieurs classes, une seule doit être public. Le nom du fichier est le même que cette classe public.

  44. Les classes et les objetsExemple de programme class Cercle { public double x, y; // Coordonnée du centre private double r; // rayon du cercle public Cercle(double r) { this.r = r; // this représente l’objet à l’origine de l’appel } public double aire() { return 3.14159 * r * r; } } public class MonPremierProgramme() { public static void main(String[] args) { Cercle c; // c est une référence sur un objet Circle, pas un objet c = new Cercle(5.0); // c référence maintenant un objet alloué en mémoire c.x = c.y = 10; System.out.println("Aire de c :" + c.aire()); } }

  45. Les classes et les objetsLa structure de classe • Une classe est un agrégat d'attributs et de méthodes : les membres • Les membres sont accessibles via une instance de la classe ou via la classe (pour les membres statiques) c.r = 3; // On accède à l'attribut 'r' de l'instance 'c' a = c.aire (); // On invoque la méthode ‘aire' de l'instance 'c' pi = Math.PI;// On accède à l'attribut statique 'PI' de la classe 'Math' b = Math.sqrt(2.0); // On invoque la méthode statique 'sqrt' //de la classe 'Math' • L'accessibilité des membres est pondérée par des critères de visibilité (public, private, ...) • Les méthodes sont définies directement au sein de la classe. • En POO pure, tous les membres données (ou variable d ’instance) doivent être privées. Il faut donc définir des méthodes publiques pour accéder/modifier leur valeur

  46. Les classes et les objetsCréation d’un objet (1) • Pour manipuler un objet, on déclare une référence sur la classe de cet objet : Cercle c; • Pour créer un objet, on instancie une classe en appliquant l'opérateur new sur un de ses constructeurs. Une nouvelle instance de cette classe est alors allouée en mémoire : c = new Cercle(5); • Toute classe possède un constructeur par défaut, implicite. Il peut être redéfini. Une classe peut avoir plusieurs constructeurs qui diffèrent par le nombre et la nature de leurs paramètres.

  47. Les classes et les objetsCréation d’un objet (2) class Cercle { double x, y, r; public Cercle(double x, double y, double r) { this.x = x; this.y = y; this.r = r;} public Cercle(Cercle c) { x = c.x; y=c.y; r=c.r;} public Cercle() { this(0.0, 0.0, 0.0);} } • Remarques : • Le constructeur de la classe Cercle a été sur-défini; Ceci est possible pour tout autre • méthode • - le mot clé this représente l’objet à l’origine de l’appel de la méthode.

  48. Les classes et les objetsDestruction d’un objet (1) • La destruction des objets est prise en charge par le garbage collector (GC) • Le GC détruit les objets pour lesquels il n’existe plus de référence • Les destructions sont asynchrones (le GC est géré dans une thread de basse priorité) • Aucune garantie n’est apportée quant à la destruction d’un objet • Si l’objet possède la méthode finalize , celle-ci est appelée lorsque l’objet est détruit

  49. Les classes et les objetsDestruction d’un objet (2) public class Point{ ... void finalize() { System.out.println("Je suis garbage collecte"); } } ... Point p1; if (condition) { Point p2 = new Point(); // c2 référence une nouvelle instance c1 = c2; } // La référence c2 n'est plus valide mais il reste une // référence,c1,sur l'instance c1=null; // L'instance ne possède plus de référence. Elle n'est plus // accessible. A tout moment le gc peut detruire l'objet.

  50. Les classes et les objetsLes attributs de classe (1) Certains attributs et certaines opérations peuvent être visibles globalement, dans toute la portée de la classe. Ces éléments, également appelés attributs et opérations de classe, sont représentés en UML comme un objet, avec leur nom souligné. Règles de visibilité • + attribut public • # attribut protégé • Attribut privé • Attribut de classe • + Opération publique( ) • # Opération protégée( ) • Opération privée( ) • Opération de classe( )

More Related