Programmation Orientée Objet Introduction à Java Julien Provillard http://www.i3s.unice.fr/~provilla/poo/ [email protected] PRÉSENTATION GÉNÉRALE 2 Programmation orientée objet Organisation du cours Volume Horaire 12 séances de 1h30 de cours magistral 12 séances de 1h30 de TP sur machine Evaluation Contrôle terminal en fin de semestre: 60% Contrôle continu en TP: 20% + 20% 3 Programmation orientée objet Ressources et références Programmer en Java, C. Delannoy, Ed. Eyrolles, 2014 Thinking in Java, B. Eckel, Prentice Hall, 2006 Traduction française diponible en ligne http://bruce-eckel.developpez.com/livres/java/traduction/tij2/ Les tutoriels Oracle https://docs.oracle.com/javase/tutorial/ La documentation de l’API standard https://docs.oracle.com/javase/8/docs/api/ 4 Programmation orientée objet Plan du cours Les bases Introduction Types primitifs et opérateurs Classes et objets Tableaux Héritage et polymorphisme Chaînes de caractères Exceptions Entrées-sorties Généricité et collections Compléments sur le langage 5 PRÉSENTATION 6 Programmation orientée objet Paradigmes de programmation Un paradigme de programmation est un ensemble de concepts et de méthodes de programmation autorisés ou interdits. Tout programme peut s’écrire dans n’importe quel paradigme mais la façon de l’exprimer change. Un paradigme va guider la conception et l’implémentation d’un algorithme. 7 Programmation orientée objet Exemples de paradigmes de programmation Programmation fonctionnelle. Un programme est une fonction (au sens mathématique du terme). Programmation impérative. Un programme est une suite d'instructions qui modifient l‘état du système. Programmation structurée. Variante de la programmation impérative, le flot d'exécution du programme est dicté par des structures de contrôle. Programmation orientée objet. Un programme est un ensemble de briques logicielles qui interagissent entre elles. 8 Programmation orientée objet La Programmation Orientée Objet Les concepts mis en avant par la POO sont L’abstraction La modularité L’encapsulation Le polymorphisme Les outils qui supportent ces concepts sont : Les classes ou les prototypes En Java L’héritage (simple ou multiple) Le système de typage (statique ou dynamique, explicite ou inféré) Points forts (supposés) Du code plus proche du monde réel et donc plus facile à assimiler et à maintenir. Stabilité accrue : les modifications ne s’appliquent que localement à des sous-systèmes. 9 Programmation orientée objet Gestion des notes d’une université Objets Etudiant Statut, matières, notes Matière Etudiants, ECTS Diplôme Année, matières Procès verbal Fonctions (méthodes) Calculer la moyenne individuelle Calculer la moyenne générale Calculer la moyenne par matière Valider l’année Déterminer les matières à rattraper Calculer les taux de réussite Etudiants, diplôme Des données Des comportements Les objets s’échangent des messages en fonction de leurs comportements associés. 10 Programmation orientée objet Historique Simula-67 : Dahl et Nygaard Smalltalk-71 : A. Kay C++ 79-85 : Stroustrup Eiffel 85 : B. Meyer Java 94-95 : J. Gosling/Sun Ruby 95 : Y. "Matz" Matsumoto C# 2000 : Microsoft Scala 2003 : Martin Odersky http://www.simula.no http://www.smalltalk.org http://www.eiffel.com http://java.sun.com http://www.ruby-lang.org http://www.learn-c-sharp.com http://www.scala-lang.org Turing Award 2001 à Dahl et Nygaard "For ideas fundamental to the emergence of object oriented programming, through their design of the programming languages Simula I and Simula 67." 11 LES NOTIONS ESSENTIELLES 12 Programmation orientée objet Types de données Réalise un Type Abstrait de données (au sens algorithmique) Un type de données définit Un domaine de valeur Un ensemble d’opérations autorisées En java, on distingue Les types primitifs (entiers, flottants, booléens, caractères) Les types référence, objets définis à partir des types primitifs et/ou d’autres types références. • Une couleur RGB est un triplet d’entiers • Une image Bitmap est un ensemble de pixels de couleur 13 Programmation orientée objet Types primitifs En java, il existe 8 types primitifs 1 type booléen : boolean 4 types entiers : byte, short, int, long 2 types flottants : float, double 1 type caractère : char A la différence d’autres langages (comme C++), la taille en mémoire des types primitifs est entièrement défini par le langage. Type Taille (en octets) byte short int long float double boolean char 1 2 4 8 4 8 1 2 14 Programmation orientée objet Variables Pour déclarer une variable, on indique son type et son nom. boolean isRunning; double precision; On peut affecter le résultat d’une expression à une variable déclarée. Une variable qui a reçu au moins une affectation est dite initialisée. isRunning = true; precision = 1.0 / 1000; Il est usuel de simultanément déclarer et initialiser une variable boolean isRunning = true; double precision = 1.0 / 1000; Il est interdit de manipuler une variable non initialisée! 15 Programmation orientée objet Type primitif boolean Valeurs : true, false Opérations autorisées Comparaisons Opérations booléennes == != ! & && | || ^ Exemples boolean estVrai = true && !false; boolean estFaux = estVrai ^ estVrai; Opérations avec court-circuit boolean erreur = false & (1 / 0 == 0); boolean correct = false && (1 / 0 == 0); 16 Programmation orientée objet Les entiers relatifs Quatre types primitifs (en fonction de leur taille) byte short int long 8 bits 16 bits 32 bits 64 bits [-128, 127] [-32768, 32767] [-231, 231 - 1] [-263, 263 - 1] Opérations autorisées Comparaisons Opérations arithmétiques Opérations binaires == != < <= > >= + - * / % & | ~ << >> >>> Exemples 13 / 6 -> 2 13 % 6 -> 1 13 & 6 -> 4 13 / 0 -> Erreur! 17 Programmation orientée objet Constantes entières On peut affecter une constante entière à une variable. byte val = 13; int val2 = 6; La constante doit être dans l’intervalle autorisé par le type. byte val = 128; On peut écrire les constantes en hexadécimal (préfixe 0x) ou en octal (préfixe 0). 31 == 0x1F && 31 == 037 // true -1 == 0xFFFFFFFF && -1 == 037777777777 // true Par défaut, les constantes entières sont de type int. On peut les forcer à être de type long à l’aide du suffixe L. long val = 0x100000000; long val = 0x100000000L; -1 != 0xFFFFFFFFL && -1 != 037777777777L // true 18 Programmation orientée objet Les nombres flottants Deux types primitifs (en fonction de leur taille) Type Taille Valeur absolue minimale Valeur absolue Maximale float 32 bits 1.40239846e-45 3.40282347e38 double 64 bits 4.9406564584124654e-324 1.797693134862316e308 Opérations autorisées Comparaisons Opérations arithmétiques == != < <= > >= + - * / Exemples 13.0 / 2.0 -> 6.5 13.0 / 0.0 -> +∞ Les opérations arithmétiques ne produisent jamais d’erreur sur les nombres flottants. 19 Programmation orientée objet Constantes flottantes On peut affecter une constante flottante à une variable. double val = 13.0; double val = 1.3e1; La constante doit avoir un valeur absolue autorisée par le type. double val = 10e308; Par défaut, les constantes flottantes sont de type double. On peut les forcer à être de type float à l’aide du suffixe f. float val = 0.1; float val = 0.1f; Le calcul sur les nombres flottants est sujet aux erreurs de précision. 0.8 == 0.4 + 0.4; // true 0.8 == 0.7 + 0.1; // false Il existe des constantes spéciales pour les nombres flottants. Float.POSITIVE_INFINITY Double.POSITIVE_INFINITY Float.NEGATIVE_INFINITY Double.NEGATIVE_INFINITY Float.NaN Double.NaN 20 Programmation orientée objet Type primitif char Représente les caractères. Le codage retenu est l’Unicode 16 bits. Opérations autorisées Comparaisons == != < <= > >= Exemples char c = 'c'; c = '\u00e9'; c = '\t'; c = '\n'; c = '\\'; c = '\''; // // // // // // code ASCII 99 code unicode 00e9 => é la tabulation, code unicode 0009 le saut de ligne, code unicode 0010 le slash le quote 21 Programmation orientée objet Opérations et promotion Exemple de l’addition int +(int, int) long +(long, long) float +(float, float) double +(double, double) Promotion byte -> short -> int -> long -> float -> double char -> int -> long -> float -> double Exemples 1 + 2L; 1 + 2.0; 'e' - 'a'; 2014-2015 // 3L // 3.0 // 4 J. Provillard - POO 22 Programmation orientée objet Affectations combinées += Incrémente une variable <variable> += <expression>; Attention Surchargée pour tous les types numériques • byte, short, int, long, float, double Différent d’une addition • byte b = 127; • b = b + b; int +(int, int) Variantes b += b; byte +=(int) -= *= /= <<= >>= >>>= &= |= b++ ++b &&= et ||= n’existent pas! 2014-2015 J. Provillard - POO 23 Programmation orientée objet Cast Par promotion, on peut écrire : byte shortVar = 10; int var = shortVar; // var = 10 Par contre, l’affectation suivante est interdite : int var = 10; byte shortVar = var; // un byte n’est pas assez grand pour contenir un int Dans ce cas précis, la valeur est pourtant compatible, on peut forcer la conversion à l’aide d’un cast : int var = 10; byte shortVar = (byte)var; // shortVar = 10 Il est possible de perdre de l’information lors d’une conversion. byte b = (byte)257; // b = 1 24 Programmation orientée objet Structure de contrôle : if La syntaxe du branchement conditionnelle est if (condition) instruction_1 [else instruction_2] Une instruction peut-être une expression terminée par un point virgule (une instruction simple) Un bloc d’instructions entre accolades if (x % 2 == 0) x /= 2; // instruction simple else { // bloc x *= 3; x++; } if (x % 2 == 0) { // mieux x /= 2; } else { x *= 3; x++; } Un bloc peut se limiter à une seule instruction. On conseille de toujours utiliser un bloc pour les structures de contrôle. 25 Programmation orientée objet Structure de contrôle : switch La structure switch permet de faire un branchement multiple. switch (expression) { case constante_1: [instructions_1] case constante_2: [instructions_2] ... case constante_k: [instructions_k] [default: instructions] } Cherche la première constante égale à l’expression et exécute les instructions qui suivent. Si aucune constante ne correspond, réalise les instructions par défaut. La structure est limitée aux valeurs entières. 26 Programmation orientée objet Structure de contrôle : switch Exemple : int x = 2; switch (x % 2) { case 0: x /= 2; case 1: x *= 3; x++; default: x = -1; } x == ? 27 Programmation orientée objet Structure de contrôle : switch Exemple : int x = 2; switch (x % 2) { case 0: x /= 2; case 1: x *= 3; x++; default: x = -1; On branche ici. Donc toutes ces instructions sont exécutées On ajoute le mot clé break pour sortir d’un cas. } x == -1 28 Programmation orientée objet Structure de contrôle : switch Exemple : int x = 2; switch (x % 2) { case 0: x /= 2; break; case 1: x *= 3; x++; break; default: x = -1; } On branche ici. On sort ici. On ajoute le mot clé break pour sortir d’un cas. x == 1 29 Programmation orientée objet Structure de contrôle : while La syntaxe de la boucle while est while (condition) instruction Tant que la condition est vraie, on exécute le corps de la boucle. Variante la boucle do while do instruction while (condition); On exécute le corps de la boucle tant que la condition est vraie. Le corps s’exécute au moins une fois. Le point virgule fait partie de la syntaxe. 30 Programmation orientée objet Structure de contrôle : for La syntaxe de la boucle for est for ([initialisation]; [condition]; [incrémentation]) instruction L’initialisation est une déclaration ou une suite d’expressions séparées par des virgules. L’incrémentation est une suite d’expressions séparées par des virgules. La condition est une expression booléenne. Si aucune condition n’est donnée, la boucle est infinie. int somme = 0; for (int i = 0; i < 10; i++) { somme += i; } for (int i = 1, j = 8; j >= 0; i *= 2, j--) { System.out.println("i = " + i); System.out.println("j = " + j); } 31 Programmation orientée objet Les instructions break et continue On a déjà vu l’effet de break dans l’instruction switch. Dans une boucle (for, while ou do while), break sort immédiatement de la boucle. Dans une boucle, continue retourne au début du corps. S’il s’agit d’une boucle for, l’incrémentation a lieu. Ces instructions sont à éviter dans la mesure du possible car elles rendent le code moins lisible. 32 Programmation orientée objet Classe = Type composé Types primitifs normalisés par le langage boolean, char, byte, short, int, long, float, double Composition => champs (nom + type) Couleur : rouge (8 bits) + vert (8 bits) + bleu (8 bits) Image : ensemble de pixels de couleur Nom : séquence/chaîne de caractères Date : ? Compromis espace mémoire/temps de calcul Couleur : RGB vs. YUV Nombre complexe: ou 2014-2015 Complexe c = re + i.im c = z.ei.θ reelle : double imaginaire : double J. Provillard - POO 33 Programmation orientée objet Classe : encodage Couleur Complexe class CouleurRGB { byte rouge; byte vert; byte bleu; } class ComplexeCartesien { double reelle; double imaginaire; } class CouleurYUV { byte luminance; byte chrominanceRouge; byte chrominanceBleue; } class ComplexePolaire { double module; double argument; } 2014-2015 J. Provillard - POO 34 Programmation orientée objet Objet = instance d’une classe Type Classe → → valeurs objets → → variables références Complexe reelle : double imaginaire : double Complexe c1; // référence c1 = new Complexe(1, -1); Complexe c2; // référence c2 = new Complexe(2, 0); c1 : Complexe c1 2014-2015 c2 : Complexe c2 J. Provillard - POO 35 Programmation orientée objet Méthode = opération sur les objets Norme d’un complexe class ComplexeCartesien { double re; double im; class ComplexePolaire { double module; double argument; double norme() { return re * re + im * im; } double norme() { return module * module; } double argument() { return Math.atan2(im, re); } double argument() { return argument; } } 2014-2015 } J. Provillard - POO 36 Programmation orientée objet Notation pointée Pour accéder aux membres d’un objet Membre = champs + méthodes Complexe reelle : double imaginaire : double Exemple Complexe c1 = new Complexe(); norme() : double c1.reelle désigne le champ reelle de c1 c1.norme() désigne la méthode norme de c1 2014-2015 J. Provillard - POO 37 Programmation orientée objet Méthodes et paramètres Données supplémentaires Le calcul de la norme nécessite seulement la valeur de ‘reelle’ et de ‘imaginaire’ Certaines méthodes nécessitent des paramètres • Signature int addition(int, int); • Corps int addition(int x, int y) { return x + y ; } 2014-2015 J. Provillard - POO 38 Programmation orientée objet Classe Moyenne class Moyenne { // bloc de déclaration de classe /* Somme des notes obtenues */ int notes = 0; /* Nombre de notes obtenues */ int nombreDeNotes = 0; /* Ajoute une note à la moyenne */ void ajouteNote(int note) { notes += note; nombreDeNotes += 1; } /* Renvoie la moyenne des notes */ double calculMoyenne() { return ((double) notes) / nombreDeNotes; } } 2014-2015 J. Provillard - POO 39 Programmation orientée objet Classe String Classe qui représente une séquence de caractères Classe spéciale (utilisation très fréquente) • Pas besoin d’utiliser new pour créer des instances String str = "Un exemple!"; • Les objets sont immutables (on ne peut pas les modifier) L’expression "rou" + "ge" fait intervenir 3 objets différents Concaténation int x = 20, y = 40; "Je place " + x + " euros." x + y + " euros sont placés." "Je place " + x + y 2014-2015 "Je place 20 euros." "60 euros sont placés." "Je place 2040" J. Provillard - POO 40 Programmation orientée objet Vocabulaire m1 0 12 0 1 2014-2015 J. Provillard - POO 41 ENVIRONNEMENT DE DÉVELOPPEMENT 42 Programmation orientée objet Compilateur L’ordinateur (son processeur) ne comprend pas le code Java (code source) Un interpréteur interprète directement le code source (langage interprété) Le compilateur traduit (compile) le code source Vers du code binaire natif (langage compilé) • Spécifique à un processeur donné • Spécifique au système d’exploitation utilisé Vers un langage neutre (ex: bytecode) • Ce langage neutre est alors interprété par la machine virtuelle java (Java Virtual Machine JVM) 2014-2015 J. Provillard - POO 43 Programmation orientée objet Processus de compilation en Java Fichier source Test.java Compilation (JDK) javac Test.java interprétation bytecode java Test Test.class API JRE Write once, Run everywhere OS Processeur 2014-2015 J. Provillard - POO JRE 7.0 Windows, Mac, Linux Intel, AMD, ARM 44 Programmation orientée objet Méthode main – java Test Test.java: Moyenne.java: public class Test { class Moyenne { int notes = 0 ; int nombreDeNotes = 0 ; Moyenne e = new Moyenne(); void ajouteNote (int note) { notes += note; nombreDeNotes += 1; } e.ajouteNote(8); e.ajouteNote(18); e.ajouteNote(12); double m = e.calculMoyenne(); } double calculMoyenne() { return ((double)notes) / nombreDeNotes ; } } 45 Programmation orientée objet Méthode main – java Test Test.java: public class Test { public static void main(String[] args) { Moyenne e = new Moyenne(); e.ajouteNote(8); e.ajouteNote(18); e.ajouteNote(12); double m = e.calculMoyenne(); System.out.println("Moyenne=" + m); } } 46 Programmation orientée objet Méthode main – java Test Test.java: public class Test { public static void main(String[] args) { Moyenne e = new Moyenne(); e.ajouteNote(8); e.ajouteNote(18); e.ajouteNote(12); double m = e.calculMoyenne(); System.out.println("Moyenne=" + m); } } > dir Moyenne.java Test.java > javac Test.java > dir Moyenne.class Moyenne.java Test.class Test.java > java Test Moyenne = 12.666666666666666 47