See discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/315808945 Programmation Orientée Objet en Java Book · January 2016 CITATIONS READS 0 439 1 author: Djelloul Bouchiha Ctr univ Naama, EEDIS Labo, UDL-SBA 67 PUBLICATIONS 184 CITATIONS SEE PROFILE Some of the authors of this publication are also working on these related projects: Services Web Sémantiques View project Arabic Question Answering System View project All content following this page was uploaded by Djelloul Bouchiha on 24 March 2019. The user has requested enhancement of the downloaded file. REPUBLIQUE ALGERIENNE DEMOCRATIQUE ET POPULAIRE MINISTERE DE L’ENSEIGNEMENT SUPERIEUR ET DE LA RECHERCHE SCIENTIFIQUE CENTRE UNIVERSITAIRE SALHI AHMED DE NAAMA INSTITUT DES SCIENCES ET TECHNOLOGIQUES DEPARTEMENT DE MATHEMATIQUES ET INFORMATIQUE Programmation Orientée Objet en Java Support de cours destiné aux étudiants de la 2ième année Licence Informatique, Option : Systèmes Informatiques (SI), Semestre 3. Par Dr Djelloul BOUCHIHA [email protected] Année universitaire 2016-2017 Table des matières AVANT PROPOS.................................................................. 1 INTRODUCTION GENERALE.......................................... 2 CHAPITRE I : PROGRAMMATION CLASSIQUE EN JAVA : RAPPEL ................................................................... 3 1. Introduction au langage Java ............................................................. 3 2. Syntaxe du langage java ...................................................................... 6 3. Variables et type de données ............................................................... 6 3.1. Les identificateurs .......................................................................... 6 3.2. Mots clés......................................................................................... 6 4. Types ..................................................................................................... 7 4.1. Types primitifs ............................................................................... 7 4.2. Types classes d’objet ...................................................................... 7 5. Déclaration des variables .................................................................... 8 5.1. Variables ......................................................................................... 8 5.2. Constantes ...................................................................................... 8 6. L’affectation ......................................................................................... 9 7. Description des principaux opérateurs .............................................. 9 7.1. Opérateur d’affectation ................................................................... 9 7.2. Opérateurs arithmétiques à deux opérandes ................................... 9 7.3. Opérateurs à un opérande ............................................................. 10 7.4. Opérateurs relationnels ................................................................. 10 7.5. Opérateurs arithmétiques binaires ................................................ 11 7.6. L’opérateur à trois opérandes ....................................................... 11 7.7. Opérateurs logiques ...................................................................... 12 7.8. Priorité des opérateurs .................................................................. 12 8. Structures de contrôle et méthodes .................................................. 13 9. Chaîne de caractères ........................................................................... 18 10. Les tableaux ...................................................................................... 19 10.1. Déclaration d’un tableau ............................................................. 19 10.2. Tableaux multidimensionnels ..................................................... 20 11. Les opérations d'entrée sortie ......................................................... 20 12. Lecture et écriture dans un fichier texte ........................................ 22 13. Exercices ........................................................................................... 23 14. Correction des exercices .................................................................. 26 CHAPITRE II : PROGRAMMATION ORIENTEE OBJET : CONCEPTS DE BASE ....................................... 35 1. Introduction........................................................................................ 35 2. La notion d'objet ................................................................................ 35 3. La notion de classe ............................................................................. 36 4. Héritage .............................................................................................. 37 4.1. La notion d'héritage ...................................................................... 37 4.2. Hiérarchie de classes .................................................................... 37 4.3. Héritage multiple .......................................................................... 38 5. Encapsulation ..................................................................................... 38 5.1. Le concept d'encapsulation ........................................................... 38 5.2. Niveaux de visibilité ..................................................................... 39 6. Polymorphisme................................................................................... 39 6.1. Définition du polymorphisme ....................................................... 39 6.2. Types de polymorphisme ............................................................. 39 6.2.1. Le polymorphisme ad hoc ..................................................... 40 6.2.2. Le polymorphisme d'héritage ................................................ 40 6.2.3. Le polymorphisme paramétrique........................................... 40 CHAPITRE III : LA PROGRAMMATION ORIENTEE OBJET EN JAVA ................................................................ 41 1. Introduction........................................................................................ 41 2. Classes et Objets................................................................................. 41 2.1. Classe ........................................................................................... 41 2.2. Objet ............................................................................................. 42 2.3. Constructeur de la classe .............................................................. 42 3. Construction d’un programme Java ................................................ 43 4. Classes imbriquées ............................................................................. 45 5. Héritage en Java................................................................................. 46 6. L’encapsulation en Java .................................................................... 48 7. Polymorphisme en Java ..................................................................... 50 7.1. Polymorphisme paramétrique ....................................................... 51 7.2. Polymorphisme d’héritage ............................................................ 52 7.3. Polymorphisme ad hoc ................................................................. 54 8. Le mot clé static.................................................................................. 56 8.1. Les attributs statiques ................................................................... 56 8.2. Les méthodes statiques ................................................................. 57 8.3. Le mot clé final ............................................................................. 59 9. Cycle de vie d’un objet ...................................................................... 59 9.1. Allocation en mémoire et construction des objets ........................ 59 9.2. Le mot clé this .............................................................................. 60 9.3. Libération de l’espace mémoire ................................................... 61 10. Exercices ........................................................................................... 61 10.1. Série 1 : Calcul des impôts locaux .............................................. 61 10.2. Série 2 : Gestion d’une collection d’objets ................................. 65 11. Correction des exercices .................................................................. 69 11.1. Série 1 : Calcul des impôts locaux .............................................. 69 11.2. Série 2 : Gestion d’une collection d’objets ................................. 71 CONCLUSION GENERALE ............................................ 78 REFERENCES BIBLIOGRAPHIQUES ADDITIONNELLES ........................................................... 80 ANNEXE .............................................................................. 81 Liste des Figures Figure I.1 : Cycle d’exécution d’un programme Java ..................... 5 Figure I.2 : Flux d’entrée/sortie en Java ....................................... 20 Figure II.1 : Abstraction de quelques objets du monde réel ......... 37 Figure II.2 : Exemple de diagramme de classe ............................. 38 Figure II.3 : Exemple d’héritage multiple .................................... 38 Figure III.1 : Représentation en mémoire d’une instanciation ..... 60 Liste des Tableaux Tableau I.1 : Types primitifs du langage Java ................................ 7 Tableau I.2 : Différentes formes de l’opérateur d’affectation du langage Java ..................................................................................... 9 Tableau I.3 : Opérateurs arithmétiques à deux opérandes .............. 9 Tableau I.4 : Opérateurs arithmétiques à un seul opérande .......... 10 Tableau I.5 : Opérateurs relationnels du langage Java ................. 10 Tableau I.6 : Opérateurs arithmétiques binaires du langage Java . 11 Tableau I.7 : Opérateurs bit level.................................................. 11 Tableau I.8 : Opérateur à trois opérandes ..................................... 11 Tableau I.9 : Opérateurs logiques ................................................. 12 Tableau I.10 : Priorités entre les opérateurs .................................. 12 Tableau I.11 : Eléments de base du langage Java ......................... 13 Tableau I.12 : Caractères spéciaux issus du type char .................. 19 Tableau I.13 : Les méthodes de lecture au clavier dans la classe Readln ............................................................................................ 21 Avant Propos Le cours Programmation Orientée Objet en Java est le fruit des années d’enseignement. C’est un cours simple avec des exercices corrigés. En effet, notre objectif était de simplifier les notions OO en les rapprochant au monde réel. Ce cours est dédié aux étudiants de la 2ième année Licence Informatique, Option : Systèmes Informatiques (SI), Semestre 3, Matière Programmation Orientée Objet. Ce document est organisé comme suit : Introduction générale Chapitre 1 : Présentation du langage java, une grande partie de son vocabulaire est introduite. Chapitre 2 : Présente les notions de base de la programmation OO. Chapitre 3 : Programmer OO en langage Java. Conclusion Références bibliographiques additionnels pour élargir et étendre les connaissances dans le domaine de la programmation orientée objet. Une annexe montrant le programme officiel de la matière en question, issu du canevas proposé par le Comité Pédagogique National du Domaine mathématiques et informatique. Chers lecteurs, je vous souhaite une bonne lecture, et je serai ravi de recevoir vos commentaires, suggestions et corrections. 1 Introduction Générale La programmation classique ou procédurale, offerte par quelques langages de programmation, tels que Pascal, C, etc., permet de mettre en œuvre des programmes avec un ensemble de données sur lesquelles agissent des procédures ou des fonctions. La programmation orientée objet, pour sa part, tourne autour d'une unique entité, à savoir l'objet. Un objet est une structure de données qui regroupe les données et les moyens de traitement de ces données. Un objet rassemble donc deux éléments de la programmation procédurale : (1) Les attributs qui sont à l'objet ce que les variables sont à un programme. Tout comme n'importe quelle autre variable, un attribut peut posséder un type : nombre, caractère... ou même un type objet. (2) Les méthodes qui sont les éléments d'un objet qui servent d'interface entre les données et le programme. Ce sont tout simplement des procédures ou des fonctions destinées à traiter les données. L’un des plus importants langages, supportant les éléments de la Programmation Orientée Objet est bien entendu le langage Java. Java est un langage de programmation mis au point par Sun Microsystems (rachetée par Oracle en 2010) qui permet d’implémenter des logiciels indépendants de toute architecture matérielle. Le nom « Java » veut dire « café » (en argot américain). Il a été choisi en remplacement du nom d'origine « Oak », à cause d'un conflit avec une marque existante. Le logo choisi par Sun est d'ailleurs une tasse de café fumant. Dans ce qui suit nous allons présenter la syntaxe du langage Java qui reprend en grande partie la syntaxe du langage C++, très utilisé par les informaticiens. Nous allons décrire ensuite les notions de base de la programmation orientée objet indépendamment de tout langage. Enfin, nous allons apprendre comment programmer orienté objet en Java. 2 Chapitre I : Programmation classique en Java : Rappel Chapitre I : Programmation classique en Java : Rappel 1. Introduction au langage Java Java est un langage orienté objet dont la syntaxe repose sur la syntaxe du langage C et C++. Ce langage est Apparu fin 1995 début 1996, et développé par Sun Microsystems. Soit le programme Java suivant : import java.io.*; class Test { public static void main (String [] args) { System.out.println("java et la programmation OO"); } } Le programme au-dessus permet d’afficher la phrase : "java et la programmation OO". Comme illustré dans l’exemple, le programme Java est composé de : Une partie qui contient la liste des bibliothèques (appelées aussi paquetages ou packages en anglais) utilisées dans le programme. Le mot clé class suivi du nom du programme. Notons ici qu’un programme n’est enfin de compte qu’une classe. La classe du programme principal va contenir, selon les besoins du programmeur, une liste d’attributs (variables) et une liste de méthodes (procédures ou fonctions) ; parmi ces méthodes on a celle identifiée par public static void main (String [] args), dans laquelle on met les instructions à exécuter ; dans notre cas System.out.println ("…") ; permet d’afficher la phrase mentionnée. Maintenant, pour exécuter ce programme on aura besoin d’installer le JDK (Java Development Kit). Le JDK ne contient pas seulement les paquetages utilisés dans le programme Java, mais il contient aussi un ensemble d’outils 3 Chapitre I : Programmation classique en Java : Rappel permettant la manipulation, l’exécution, etc. d’un programme Java. La version utilisée pour la compilation et l’exécution des programmes de ce cours est JDK 1.4. Pour exécuter le programme au-dessus, il faut suivre les étapes suivantes : Sauvegarder le programme sous le nom Test.java. On note ici que le nom du programme est le même que celui de la classe mère dans le code du programme. Veuillez maintenant compiler le programme par la commande javac Test.java via l’invite de commande DOS, ensuite appuyez sur Entrée. S’il n’y a aucune erreur dans votre programme, vous allez remarquer la création d’un fichier nommé Test.class. Pour exécuter maintenant votre programme, veuillez tapez la commande : java Test, ensuite la valider par Entrée. Vous allez voir le résultat d’exécution de votre programme. Comme résultat d’exécution, le programme Java va afficher la phrase : java et la programmation OO Remarque : Pour éviter de reprendre ce travail chaque fois qu’on veut exécuter un programme Java, il est possible d’utiliser des éditeurs configurables une seule fois et facilitant ainsi la programmation en Java. Parmi ces éditeurs on cite Kawa, Eclipse, etc. Le cycle d’exécution d’un programme java peut être représenté dans la figure suivant : 4 Chapitre I : Programmation classique en Java : Rappel Code source import java.io.*; class Test { public static void main (String [] args) { System.out.println("java et la programmation OO"); } } 1) Compilation Fichier compilé ou bytecode 1000 1100 1010 0000 1001 1110 1000 0110 0010 0000 ….. JVM Lecture du fichier local ou à distance JVM JVM 2) Interprétation Sun Mac PC Figure I.1 : Cycle d’exécution d’un programme Java Le code source du programme Java sera lu, ensuite compilé par le compilateur Java ; comme résultat de cette opération un fichier compilé (bytecode) sera généré. Le fichier compilé sera exécuté par la JVM. La machine virtuelle JAVA ou JVM (Java Virtual Machine) est un ordinateur virtuel capable d’exécuter des programmes Java compilés. La machine est virtuelle parce qu’elle est en général implémentée sous forme d’un programme au sommet d’un système d’exploitation sur une vraie machine. La machine virtuelle JAVA doit être d’abord installée sur un ordinateur, avant de pouvoir faire tourner des programmes. Elle peut accompagner l’installation du JDK dans un répertoire appelé JRE (Java Resume Environment). Grâce à la JVM, on peut dire que Java est un langage multiplateforme. 5 Chapitre I : Programmation classique en Java : Rappel 2. Syntaxe du langage java Comme en C, les instructions Java sont séparées par des points virgules (;). Pour les commentaires on a : Les commentaires sur une ligne débutent par //.... Les commentaires sur plusieurs lignes sont délimités par /* ... */. 3. Variables et type de données Chaque variable est désignée par un identificateur, et possède un type de données. 3.1. Les identificateurs Un identificateur est une suite de lettres (minuscules ou majuscules) et de chiffres. En plus des lettres, les caractères suivants sont autorisés pour construire un identificateur Java : "$" , "_" , "μ" et les lettres accentuées. Un identificateur ne doit pas commencer par un chiffre. Java distingue entre minuscules et majuscules (Valeur diffère de VALEUR). Les mots clés du langage Java ne peuvent être utilisés comme identificateurs. 3.2. Mots clés Les mots clés du langage Java sont les suivants : abstract boolean break byte case catch char class const continue default do double else extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static super switch synchronized this throw throws transient try void volatile while static 6 Chapitre I : Programmation classique en Java : Rappel 4. Types En Java, les types peuvent être classés en deux catégories : types primitifs (prédéfinis ou élémentaires), et types par référence (ou classes d’objet). 4.1. Types primitifs Les types primitifs sont représentés dans le tableau suivant : Tableau I.1 : Types primitifs du langage Java Type élémentaire boolean byte char double float int long short Intervalle de variation false , true [-128 , +127] Caractères Virgule flottante double précision [1.7e-308, 1.7e308] Virgule flottante simple précision [3.4e-38, 3.4e+38] entier signé : [-231, +231 - 1], i.e. [-2147483 648…2147483647] entier signé long : [-263, +263- 1], i.e. [-9223372036854775808, 9223372036854775807] entier signé court : [-215, +215 -1], i.e. [-32768, 32767] Nombre de bits 1 bit 8 bits 16 bits 64 bits 32 bits 32 bits 64 bits 16 bits 4.2. Types classes d’objet Les types classes sont : Boolean, Byte, Character, Short, Integer, Long, Float et Double. Une variable de ce type est accessible via des méthodes : La déclaration d’une variable de type classe d’objet se fait par le mot clé new qui permet d’instancier une classe. Par exemple : Integer un = new Integer(1); La Méthode xxxValue(), où xxx est l’un des noms du type primitif correspondant, permet d’obtenir une variable du type primitif correspondant. L'opérateur instanceof permet de tester si un objet est une instance d’une classe donnée (ou de l'une de ses sous-classes). L’opérateur instanceof ne permet pas de tester le type d’une primitive. 7 Chapitre I : Programmation classique en Java : Rappel class classes_objet { public static void main (String [] args) { Integer un = new Integer(1); int i = un.intValue(); boolean a = un instanceof Integer ; System.out.println(i); System.out.println(a); } } Cet exemple affiche : 1 true Remarque : Java ne dispose pas de type pointeur. 5. Déclaration des variables Java permet de déclarer des variables et des constantes. 5.1. Variables La déclaration d’une variable consiste à associer un type à un identificateur. La syntaxe générale est : <type> variable ;. Par exemple, pour déclarer une variable entière i et une variable booléenne test on écrira : int i ; boolean test ; Il est possible d’initialiser une variable lors de sa déclaration : int i = 4 ; 5.2. Constantes Il est possible de simuler l’utilisation des constantes à l’aide du mot clé final. Une variable déclarée final ne peut plus être modifiée une fois qu’elle a été initialisée. Par exemple : final int x =5 ; 8 Chapitre I : Programmation classique en Java : Rappel 6. L’affectation Syntaxe générale est : <variable> = <valeur> ;. Le symbole d’affectation en Java est donc ‘=’. Par exemple i = 2 + 3 ; met la variable i à 5. Les formes suivantes sont aussi permises : int a , b = 56 ; // a, b deux valeurs entières avec b initialisée à 56 a = (b = 12)+8 ; // b prend la valeur 12 et a prend la valeur 20 a = b = c = d =8 ; // affectation multiple : a, b, c, d prennent la valeur 8 7. Description des principaux opérateurs Une expression arithmétique ou logique est constituée d’un ou plusieurs opérandes séparés par des opérateurs. 7.1. Opérateur d’affectation Le tableau suivant décrit les différentes formes de l’opérateur d’affectation : Tableau I.2 : Différentes formes de l’opérateur d’affectation du langage Java Opération Symbole Description Exemple équivalente = affectation x=2 x=2 soustraction et -= x-= 2 x=x-2 affectation addition et += x += 2 x=x-2 affectation Opérateur multiplication et d’affectation *= x *= 2 x=x*2 affectation division et /= x /= 2 x=x/2 affectation modulo et x %= 2 %= x=x%2 affectation On dispose du raccourci : x = y = z = 2 ; 7.2. Opérateurs arithmétiques à deux opérandes Le tableau suivant décrit les opérateurs arithmétiques à deux opérandes : Tableau I.3 : Opérateurs arithmétiques à deux opérandes Symbole Description Exemple + adition x+y – soustraction y–x Opérateurs * multiplication 3*x arithmétiques à deux opérandes / division 4/2 % modulo (reste de la division) 5%2 9 Chapitre I : Programmation classique en Java : Rappel 7.3. Opérateurs à un opérande Le tableau suivant décrit les opérateurs arithmétiques à un opérande : Tableau I.4 : Opérateurs arithmétiques à un seul opérande Symbole – ++ Opérateurs à un opérande ++ --- Description opposé pré-incrémentation (incrémentation ensuite utilisation) post-incrémentation (utilisation ensuite incrémentation) pré-décrémentation post-décrémentation class IncDec { public static void main(String [] args) { int a = 1; int b = 2; int c = ++b; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); System.out.println("d = " + d); } } Exemple –x ++x x++ --x x-- int d = a++; c++; La sortie du programme est : a=2 b=3 c=4 d=1 7.4. Opérateurs relationnels Le tableau suivant décrit les opérateurs relationnels : Tableau I.5 : Opérateurs relationnels du langage Java Opérateurs relationnels Symbole == < > <= >= != Description équivalent plus petit que plus grand que plus petit ou égal plus grand ou égal non équivalent Exemple x == 0 x<2 x>2 x <= 3 x >= 3 a != b 10 Chapitre I : Programmation classique en Java : Rappel 7.5. Opérateurs arithmétiques binaires Les opérateurs arithmétiques binaires agissent au niveau des bits de données, sans tenir comte de ce qu’ils représentent. Le tableau suivant décrit les opérateurs arithmétiques binaires : Tableau I.6 : Opérateurs arithmétiques binaires du langage Java Opérateurs arithmétiques binaires Symbole & | ^ ~ << >> >>> Description et ou ou exclusif non décalage à gauche décalage à droite décalage à droite sans extension du signe Exemple a&b a|b a^b ~a a << 2 b >> 2 b >>> 2 Par exemple, si on a : int a = -1; a = a >>> 24; donne en forme binaire : 11111111111111111111111111111111 -1 >>>24 00000000000000000000000011111111 255 La table de vérité des opérateurs bit level est la suivante : Tableau I.7 : Opérateurs bit level p 1 1 0 0 q 1 0 1 0 ~p 0 0 1 1 p&q 1 0 0 0 p|q 1 1 1 0 p^q 0 1 1 0 On peut utiliser les opérateurs arithmétiques binaires avec des valeurs logiques, qui sont des valeurs sur 1 bit. 7.6. L’opérateur à trois opérandes Le tableau suivant décrit un opérateur à trois opérandes : Tableau I.8 : Opérateur à trois opérandes opérateur à trois opérandes Symbole Description ?: condition ? A : B Exemple y<5?4*y:2 *y 11 Chapitre I : Programmation classique en Java : Rappel Si la condition est VRAI, alors on retourne la valeur de l’expression A, sinon on retourne celle de B. Par exemple : class Trois_Operandes { public static void main (String [] args) { int x, y=3; x= y < 5 ? 4 * y : 2 * y; System.out.println(x); } } Le programme Java affiche : 12. 7.7. Opérateurs logiques Le tableau suivant décrit les opérateurs logiques : Tableau I.9 : Opérateurs logiques Opérateurs Logiques Symbole && || ! Description ET logique OU logique NON logique Exemple (x>10) && (x<15) (x>10) || (y<10) ! (x >= 0) 7.8. Priorité des opérateurs Les opérateurs par ordre de préséance décroissante sont présentés dans le tableau suivant : Tableau I.10 : Priorités entre les opérateurs Opérateurs Appel de méthode [ ] . () ++ -- ! -(unaire) ()(cast) new * / % + << >> >>> > >= < <= instance of == != & ^ | && || ?: = op= Ordre d’évaluation gauche à droite droite à gauche gauche à droite gauche à droite droite à gauche gauche à droite gauche à droite droite à gauche 12 Chapitre I : Programmation classique en Java : Rappel 8. Structures de contrôle et méthodes Le tableau suivant décrit les structures de contrôle (structures conditionnelles et boucles), ainsi que les sousprogrammes (méthodes : fonctions et procédures) qui peuvent apparaître dans un programme java. Tableau I.11 : Eléments de base du langage Java Structure de contrôle Syntaxe if (condition) instruction ; instruction conditionnelle if if (condition) {bloc d’instructions} Commentaires Exemple Résultat affiché par le programme La condition est une expression booléenne qui retourne true ou false. Les parenthèses sont obligatoires en Java autour de la condition. Les accolades sont obligatoires pour un ensemble d’instructions et facultatives pour une seule instruction. 13 Chapitre I : Programmation classique en Java : Rappel if (condition) instruction ; else instruction ; instruction conditionnelle if else la boucle for if (condition) {bloc d’instructions} else {bloc d’instructions} for (initialisation ; test ; incrémentation) {bloc d’instructions} la partie initialisation se compose d’une ou plusieurs initialisations (séparées par des virgules). La partie test est une expression booléenne. La partie incrémentation peut contenir plusieurs instructions séparées par des virgules. class Inst_if { public static void main (String [] args) { int a , b , c ; a=b=c=1; if ( b == 0 ) c =1 ; else { c = a / b; System.out.println("c = " + c); } if ((c = a*b) != 0) c += b; else c = a; System.out.println("c = " + c); } } class Inst_fot { public static void main (String [] args) { System.out.println("Première boucle"); for ( int i = 1; i<=5; i++ ) System.out.println(i); System.out.println("deuxième boucle"); int i, k; c=1 c=2 Première boucle 1 2 3 4 5 deuxième boucle 10 10 -5 20 -20 15 14 Chapitre I : Programmation classique en Java : Rappel for ( ; ; ); est une boucle infinie. Dans une boucle for (int i=0 ;... ;…), la portée de la variable i est limitée au bloc du for. Une fois la boucle finie, la variable i n’est plus accessible. break ; Interruption de l’itération en cours et passage à l’instruction qui suit la boucle. continue ; Interruption de l’itération en cours et retour au début de la boucle avec exécution de la partie incrémentation. utilisation de break et continue dans les boucles for (i = 10, k = i ;i>-45 ; k += i , i -= 15) { System.out.println(i+" "+k); } } } -35 -5 class breakcontinue { public static void main (String [] args) { System.out.println("Inst break"); for ( int i = 1; i<=5; i++ ) if (i != 3) System.out.println(i); else break; System.out.println("Inst continue"); for ( int i = 1; i<=5; i++ ) { if (i == 3) continue; System.out.println(i); } } } Inst break 1 2 Inst continue 1 2 4 5 15 Chapitre I : Programmation classique en Java : Rappel class Inst_while { while (condition) {bloc d’instructions} C’est la boucle Tant que do {bloc d’instructions} while (condition) Équivalente à Répéter en algorithmique l’instruction while l’instruction switch switch (expression) { case valeur1 : instructions1 ; case valeur2 : instructions2 ; … default : instructions ; } Les blocs sont délimités par deux instructions case. Lorsqu’une égalité est trouvée, le bloc d’instruction correspondant est exécuté, ainsi que tous les blocs suivants. Pour qu’un seul bloc soit exécuté, il faut utiliser explicitement l’instruction break. public static void main (String [] args) { int i =0; while (i<5) { System.out.println(i); i++; } } } class Inst_switch { public static void main (String [] args) { int i =5; switch (i*2) { case 1 : System.out.println("Un"); break; case 2 : System.out.println("Deux"); break; default : System.out.println("Erreur"); } }} 0 1 2 3 4 Erreur 16 Chapitre I : Programmation classique en Java : Rappel return ; retour d’une méthode return (valeur ou expression) ; L’instruction return est une instruction qui peut apparaître autant de fois que vous le désirez dans le corps d’une fonction. Le type d’expression doit évidemment correspondre au type du résultat déclaré dans l’entête de la fonction. Si votre fonction ne renvoie pas de résultat (il s’agit donc d’une procédure), le type de l’entête est void et le retour s’écrit simplement return ;. Dans le cas d’une méthode void, return est facultative. Dans une méthode, le passage des paramètres est par valeur uniquement. L’ordre des méthodes n’a pas d’influence sur l’exécution du programme. bonjour Pr = 18 class METH { public static void bnj () { System.out.println("bonjour"); } public static int produit (int x, int y) { return x*y; } public static void main (String [] args) { bnj(); System.out.println("Pr = "+ produit(9,2)); } } 17 Chapitre I : Programmation classique en Java : Rappel 9. Chaîne de caractères En Java, les chaînes de caractères sont des objets. Ce sont des instances de la classe String. Les chaînes de caractères peuvent être initialisées à une valeur quelconque. La déclaration d’une chaîne de caractères peut être de deux manières : 1. Directement : String y = "bonjour" ;. Ou bien String y ; y = "bonjour" ; 2. Par le mot clé new qui permet d’instancier une classe, c’est-à-dire de créer une instance de cette classe : String y = new String("bonjour") ; Les chaînes de caractères existent aussi sous forme littérale. Il suffit de placer la chaîne entre guillemets comme dans l’exemple suivant : "Bonjour !". Les chaînes de caractères disposent de l'opérateur + qui permet de concaténer deux chaînes ; += est aussi valable pour les chaînes de caractères. Par exemple, suite à la déclaration précédente de S, l’instruction S+= " Ahmed" ; renvoie "bonjour Ahmed" à S. La méthode length retourne la longueur d’une chaîne de caractères. La méthode equals permet de comparer la chaîne de caractères avec une autre : class Type_String { public static void main (String [] args) { String x = "Ali" ; System.out.println("bonjour " + x) ; System.out.println(x.length()) ; if (! x.equals("Ahmed")) System.out.println("deux personnes differentes " ) ; } } Le programme affiche : bonjour Ali 3 deux personnes differentes 18 Chapitre I : Programmation classique en Java : Rappel Les chaînes littérales peuvent contenir des caractères spéciaux issus du type char : Tableau I.12 : Caractères spéciaux issus du type char Séquence escape \012 \uxxxx \’ \" \\ \r \n \f \t \b Description Caractère en code octal Caractère en code héxadécimal (unicode) ’ " \ Retour chariot Saut de ligne Saut de page Tabulation horizontale Backspace 10. Les tableaux Les tableaux Java sont des objets pouvant contenir un nombre fixe d’éléments de même nature. Ces éléments peuvent être à leur tour des objets ou des primitifs. Chaque élément est accessible grâce à un indice correspondant à sa position dans le tableau. 10.1. Déclaration d’un tableau La création d’un tableau peut être faite en deux étapes : 1. Déclaration de type. Les [] désignent le type tableau : int tableau_entiers[] ; 2. Allocation mémoire, via new : tableau_entiers = new int[5] ; Ou on peut mettre directement : int tableau_entiers[] = new int[5] ; Il est aussi possible d’initialiser le tableau lors de sa déclaration sans préciser la taille : int tableau_initialise[] = {12, 34, 786};. Dans ce cas, la taille est implicitement égale à 3. L’instruction System.out.println(tableau_initialise[0]+" "+tableau_initialise[1]+" "+tableau_initialise[2]) ; affiche 12 34 786. 19 Chapitre I : Programmation classique en Java : Rappel 10.2. Tableaux multidimensionnels Un Tableau à deux dimensions peut être créé comme suit : double matrice[][] = new double[4][4]; Ce qui est équivalent à : double matrice[][] = new double[4][]; matrice[0] = new double[4]; matrice[1] = new double[4]; matrice[2] = new double[4]; matrice[3] = new double[4]; Les expressions sont permises pour initialiser un tableau. Par exemple : double m[][] = { { 0*0, 1*0, 2*0 }, { 0*1, 1*1, 2*1 }, { 0*2, 1*2, 2*2 } }; L’instruction System.out.println(m[2][1]); affiche 2.0. 11. Les opérations d'entrée sortie En Java, les données (texte, image, son,...) sont échangées en entrée et en sortie (lecture et écriture) à travers des flux (Stream). Un flux est une sorte de tuyau de transport séquentiel de données. Il existe un flux pour chaque type de données à transporter. Un flux est unidirectionnel : il y a donc des flux d'entrée et des flux de sortie : Flux d’entrée Source de données Flux de sortie Source de données Application Java Application Java Figure I.2 : Flux d’entrée/sortie en Java Java met à votre disposition 3 flux spécifiques : Le flux d'entrée System.in est connecté à l'entrée standard qui est par défaut le clavier. Le flux de sortie System.out est connecté à la sortie standard qui est par défaut l'écran. Le flux de sortie System.err est connecté à la sortie standard qui est par défaut l'écran. 20 Chapitre I : Programmation classique en Java : Rappel Vous avez pu remarquer que depuis le début nous utilisons, pour afficher nos résultats, l'instruction System.out.println(...);. Il n'y a pas en Java quelque chose qui ressemble à l'instruction readln du Pascal. Java ne fournit qu’une simple instruction de lecture montrée dans l’exemple suivant : public static void main(String[] args) throws IOException { System.out.println("Appuyez sur la touche <Entrée> :"); //message écran System.in.read( ); // attend la frappe clavier de la touche <Entrée> } Afin de pallier à cet inconvénient, vous devez écrire vousmême une classe Readln avec une méthode de lecture au clavier pour chaque type élémentaire. En mettant le fichier Readln.class dans le même dossier que votre application, vous pouvez vous servir de cette classe pour lire au clavier dans vos programmes n'importe quelle variable de type élémentaire. Les méthodes de lecture au clavier dans la classe Readln sont : Tableau I.13 : Les méthodes de lecture au clavier dans la classe Readln String unstring( ) byte unbyte( ) short unshort( ) int unint( ) long unlong( ) double undouble( ) float unfloat( ) char unchar( ) Lecture au clavier d'une chaîne de type String Lecture au clavier d'un entier de type byte Lecture au clavier d'un entier de type short Lecture au clavier d'un entier de type int Lecture au clavier d'un entier de type long Lecture au clavier d'un réel de type double Lecture au clavier d'un réel de type float Lecture au clavier d'un caractère Voici un exemple d'utilisation de ces méthodes dans un programme : class ApplicationLireClavier { public static void main(String [ ] argument) { String Str; int i; long L; char k; short s; byte b; float f; double d; Readln Lire = new Readln(); System.out.print("Entrez une chaîne : "); Str = Lire.unstring( ); System.out.print("Entrez un int: "); i = Lire.unint( ); System.out.print("Entrez un long : "); L = Lire.unlong( ); 21 Chapitre I : Programmation classique en Java : Rappel System.out.print("Entrez un short : "); s = Lire.unshort( ); System.out.print("Entrez un byte : "); b = Lire.unbyte( ); System.out.print("Entrez un caractère : "); k = Lire.unchar( ); System.out.print("Entrez un float : "); f = Lire.unfloat( ); System.out.print("Entrez un double : "); d = Lire.undouble( ); }} 12. Lecture et écriture dans un fichier texte Il existe une classe dénommée File (dans java.io.File) qui est une représentation abstraite des fichiers, des répertoires et des chemins d'accès. Cette classe permet de créer un fichier, de l'effacer, de le renommer, de créer des répertoires, etc. Le programme ci-dessous contient deux procédures : Creer_Fichier permettant de créer un fichier texte et de le remplir par une phrase (Java et la programmation OO). Lire_Fichier permettant de lire le fichier déjà créé. import java.io.*; public class File_WR { public static void Creer_Fichier(String nomFichier, String ch) { try { File fichier = new File (nomFichier); FileWriter out = new FileWriter(fichier); out.write(ch); out.close( ); } catch (IOException err) { System.out.println( "Erreur : " + err ); } } public static void Lire_Fichier(String nomFichier) { try { File fichier = new File (nomFichier); FileReader in = new FileReader(fichier); int size = (int)fichier.length(); int chars_read = 0; 22 Chapitre I : Programmation classique en Java : Rappel char[] data = new char[size]; while(in.ready()) { chars_read += in.read(data, chars_read, size - chars_read); } System.out.println(data); in.close( ); } catch (IOException err) { System.out.println( "Erreur : " + err ); } } public static void main (String [] args) { Creer_Fichier("Test.txt", "Java et la programmation OO"); Lire_Fichier("Test.txt"); }} 13. Exercices Exercice 1 : Ecrire le programme Java permettant de calculer la somme des 100 premiers entiers et le produit des 10 premiers entiers avec une seule classe (un seul fichier Java). Exercice 2 : Reprendre l’exercice 1, mais cette fois-ci en séparant les calculs (somme et produit) dans deux méthodes différentes. Exercice 3 : Reprendre l’exercice 1, mais cette fois-ci avec deux classes définies dans deux fichiers Java indépendants. Les méthodes dans une classe et l’affichage dans la deuxième. Exercice 4 : Le programme Java suivant permet de lire un entier au clavier : import java.io.*; public class LectureEntier { public static void main (String [] args) { // On commence par déclarer un objet lecteur sur le clavier // Le clavier est associé à la variable System.in // Un InputStreamReader (lecteur sur un flux) est créé dessus // Puis on ajoute une couche BufferedReader nécessaire pour lire des informations par ligne 23 Chapitre I : Programmation classique en Java : Rappel BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); int valeur = 0; String chaineLue; try { // Lecture d’une ligne au clavier System.out.print("Entrer un entier : "); chaineLue = lecteurClavier.readLine(); // Conversion de la chaîne en entier valeur = Integer.parseInt(chaineLue); } catch (Exception e) { System.out.println("Erreur d’E/S " + e.getMessage()); } System.out.println("La valeur est : " + valeur); } } Essayez d’implémenter la classe Readln décrite dans le chapitre des opérations d’entrée sortie. Dans le reste des exercices vous pouvez utiliser les fonctions de la classe Readln pour la lecture d’un élément de type entier, caractère, etc., sans avoir besoin d’implémenter la partie de lecture de cet élément. Exercice 5 : Ecrire un programme Java permettant de calculer la valeur absolue d'un nombre réel x. La valeur absolue du nombre réel x est le nombre réel |x| : |x| = x , si x >= 0 et |x| = -x si x < 0. Exercice 6 : On souhaite écrire un programme Java de calcul des n premiers nombres parfaits. Un nombre est dit parfait s’il est égal à la somme de ses diviseurs, 1 compris. Par exemple : 6 = 1+2+3, est un nombre parfait. Exercice 7 : On souhaite écrire un programme Java de calcul et d'affichage des n premiers nombres premiers. Un nombre entier est premier s’il n’est divisible que par 1 et par lui-même. On doit utiliser des boucles while et do...while imbriquées. Par exemple : 37 est un nombre premier. 24 Chapitre I : Programmation classique en Java : Rappel Exercice 8 : Reprendre l’exercice précédent, mais cette fois-ci en utilisant des boucles for imbriquées. Exercice 9 : Ecrire un programme Java qui détermine et affiche la plus grande valeur des éléments d’un tableau. On complétera le programme suivant : public class Valeurmax { public static void main(String[] args) { // Définition d’un tableau de 10 entiers int [] Tableau = {5, 3, 12, 4, 7, 9, 1, 8, 19, 2}; } } Exercice 10 : Ecrire un programme Java permettant de trier, ensuite afficher un tableau d’entiers contenant les éléments : {8, 5, 7, 9, 2, 1, 12, 6}. Utiliser l’algorithme de tri par sélection. Exercice 11 : Reprendre l’exercice précédent, mais cette fois-ci il faut définir une classe TriEntiers permettant de trier des entiers stockés dans un tableau. L’en-tête de la méthode de tri est le suivant : public void TriTableauEntiers(int [] Tableau) Tester votre programme à l’aide du programme TestTriEntiers suivant : public class TestTriEntier { public static void main(String[] args) { int [] Tableau = {12, 3, 1, 4, 9, 5, 2, 8, 3, 6}; TriEntiers Tri = new TriEntiers(); Tri.TriTableauEntiers(Tableau); for (int i = 0; i < Tableau.length; i++) System.out.println(Tableau[i] + " "); } } Exercice 12 : Définir en Java une classe TriStrings contenant une fonction permettant de trier des chaînes de caractères. On utilisera la 25 Chapitre I : Programmation classique en Java : Rappel méthode compareTo de la classe String pour comparer deux chaînes de caractères. int compareTo(String s) renvoie un résultat négatif si la chaîne appelante est inférieure à s (le paramètre), 0 si elles sont égales, et un résultat positif sinon. L’en-tête de la fonction de tri est le suivant : public void TriTableauChaines(String [] Tableau) Tester votre programme TestTriChaines suivant : à l’aide du programme public class TestTriChaines { public static void main(String[] args) { String [] Tableau = {"un", "deux", "trois", "quatre", "cinq"}; TriChaines Tri = new TriChaines(); Tri.TriTableauChaines(Tableau); for (int i = 0; i < Tableau.length; i++) System.out.println(Tableau[i] + " "); } } 14. Correction des exercices Solution 1 : On définit dans la classe Calcul la méthode main qui effectue tout le traitement. class Calcul { public static void main(String[] args) { int Somme = 0; // calcul de la somme des 100 premiers entiers for (int i = 1; i <= 100; i++) Somme = Somme + i; System.out.println("La somme = " + Somme); int Produit = 1; // calcul du produit des 10 premiers entiers for (int i = 1; i <= 10; i++) Produit = Produit * i; // affiche le résultat à l'écran System.out.println("Le produit = " + Produit); } } Solution 2 : class Calcul { 26 Chapitre I : Programmation classique en Java : Rappel // Méthode de calcul de la somme des 100 premiers entiers public static int S() { int Somme = 0; for (int i = 1; i <= 100; i++) Somme = Somme + i; return Somme; } // Méthode de calcul du produit des 10 premiers entiers public static int P() { int Produit = 1; for (int i = 1; i <= 10; i++) Produit = Produit * i; return Produit; } public static void main(String[] args) { System.out.println("La somme = " + S()); System.out.println("Le produit = " + P()); } } Solution 3 : On définit la classe Calcul dans le fichier Calcul.java et la classe TestCalcul dans le fichier TestCalcul.java. Le fichier Calcul.java est défini comme suit : class Calcul { // Méthode de calcul de la somme des 100 premiers entiers public int S() { int Somme = 0; for (int i = 1; i <= 100; i++) Somme = Somme + i; return Somme; } // Méthode de calcul du produit des 10 premiers entiers public int P() { int Produit = 1; for (int i = 1; i <= 10; i++) Produit = Produit * i; return Produit; 27 Chapitre I : Programmation classique en Java : Rappel } } Le fichier TestCalcul.java est comme suit : class TestCalcul { public static void main(String[] args) { Calcul c = new Calcul(); System.out.println("La somme = " + c.S()); System.out.println("Le produit = " + c.P()); } } Solution 4 : import java.io.*; public class Readln { // Fonction de lecture d’une chaîne de caractères public static String unstring() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); String valeur = ""; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = chaineLue; } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un byte public static byte unbyte() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); byte valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Byte.parseByte(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un short 28 Chapitre I : Programmation classique en Java : Rappel public static short unshort() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); short valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Short.parseShort(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un entier public static int unint() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); int valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Integer.parseInt(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un long public static long unlong() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); long valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Long.parseLong(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } 29 Chapitre I : Programmation classique en Java : Rappel // Fonction de lecture d’un double public static double undouble() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); double valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Double.parseDouble(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un float public static float unfloat() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); float valeur = 0; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = Float.parseFloat(chaineLue); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } return valeur; } // Fonction de lecture d’un caractère public static char unchar() { BufferedReader lecteurClavier=new BufferedReader(new InputStreamReader(System.in)); char valeur = 'A'; String chaineLue; try { chaineLue = lecteurClavier.readLine(); valeur = chaineLue.charAt(0); } catch (Exception e) { System.out.println("Erreur d'E/S " + e.getMessage()); } 30 Chapitre I : Programmation classique en Java : Rappel return valeur; } } Solution 5 : Solution avec la structure if..else class ValAbs { public static void main (String [] args) { Readln Lire = new Readln(); float x; System.out.println("Entrez un nombre : "); x = Lire.unfloat(); if (x < 0) System.out.println("|x| = " + (-x) ); else System.out.println("|x| = " + (x) ); } } Solution avec la structure ?: class ValAbs { public static void main (String [] args) { Readln Lire = new Readln(); float x; System.out.println("Entrez un nombre : "); x = Lire.unfloat(); System.out.println("|x| = " + (x<0 ? -x : x) ); } } Solution 6 : class ApplicationParfaits { public static void main (String [] args) { Readln Lire = new Readln(); int compt = 0, n, k, somdiv, nbr; System.out.println("Combien de nombres parfaits : "); n = Lire.unint(); nbr = 2; while (compt != n) { somdiv = 1; k = 2; 31 Chapitre I : Programmation classique en Java : Rappel while (k <= nbr/2) { if (nbr % k == 0) somdiv+=k; k++; } if (somdiv == nbr) { System.out.println(nbr + " est un nombre parfait."); compt++; } nbr++; } } } Solution 7 : Code Java avec une boucle while et une boucle do...while imbriquées : class ApplicationComptPremiers1 { public static void main (String [] args) { Readln Lire = new Readln(); int divis, nbr, n, compt = 0; boolean Est_Premier; System.out.print("Combien de nombres premiers :"); n = Lire.unint(); System.out.println(2); nbr = 3; while (compt < n-1) { divis = 2; Est_Premier = true; do { if (nbr % divis == 0) Est_Premier = false; else divis = divis + 1; } while ((divis <= nbr/2) && (Est_Premier == true)); if (Est_Premier) { compt++; System.out.println(nbr); } nbr++; 32 Chapitre I : Programmation classique en Java : Rappel } } } Solution 8 : Code Java avec deux boucles for imbriquées : class ApplicationComptPremiers2 { public static void main (String [] args) { Readln Lire = new Readln(); int divis, nbr, n, compt = 1; boolean Est_Premier; System.out.print("Combien de nombres premiers : "); n = Lire.unint(); System.out.println(2); for (nbr = 3; compt<n ; nbr+=2) { Est_Premier = true; for (divis = 2; divis<=nbr/2; divis++) if (nbr % divis == 0) { Est_Premier = false; break; } if (Est_Premier) { compt++; System.out.println(nbr); } } } } Solution 9 : public class Valeurmax { public static void main(String[] args) { // Définition d'un tableau de 10 entiers int [] Tableau = {5, 3, 12, 4, 7, 9, 1, 8, 19, 2}; int max = Tableau[0]; for (int i=1 ; i < 10; i++ ) if (max < Tableau[i]) max = Tableau[i]; System.out.println("La valeur maximale du tableau = "+ max); }} 33 Chapitre I : Programmation classique en Java : Rappel Solution 10 : public class TriTab { public static void main(String[] args) { int [] T = {8, 5, 7, 9, 2, 1, 12, 6}; int x=0; for (int i=0; i<7; i++) for (int j=i+1; j<=7; j++) if (T[i]>T[j]) { x = T[i]; T[i] = T[j]; T[j] = x; } for (int i=0; i<=7; i++) System.out.println(T[i]); }} Solution 11 : public class TriEntiers { public void TriTableauEntiers(int [] Tableau) { int x=0; for (int i=0; i<7; i++) for (int j=i+1; j<=7; j++) if (Tableau[i]>Tableau[j]) { x = Tableau[i]; Tableau[i] = Tableau[j]; Tableau[j] = x; } } } Solution 12 : public class TriChaines { public void TriTableauChaines(String [] Tableau) { String x=""; for (int i=0; i<4; i++) for (int j=i+1; j<=4; j++) if (Tableau[i].compareTo(Tableau[j]) > 0) { x = Tableau[i]; Tableau[i] = Tableau[j]; Tableau[j] = x; } }} 34 Chapitre II : Programmation Orientée Objet : Concepts de base Chapitre II : Programmation Orientée Objet : Concepts de base 1. Introduction La programmation orientée objet (POO) signifie que l’on organise le logiciel comme une collection d’objets dissociés comprenant à la fois une structure de données et un comportement, à la différence de la programmation conventionnelle dans laquelle la structure de données et le comportement sont faiblement associés. La programmation orientée objet est caractérisée par un ensemble de concepts tels que l’objet, la classe, l’encapsulation, l’héritage et le polymorphisme. 2. La notion d'objet Un objet est une entité informatique qui modélise un élément du monde réel. Cette entité permet alors de regrouper les principales caractéristiques d’un élément du monde réel (taille, couleur, ...). La difficulté de cette modélisation consiste à créer une représentation abstraite, sous forme d'objets, des entités ayant une existence matérielle (chien, voiture, ampoule, ...) ou bien virtuelle (temps, espace ...). Un objet est caractérisé par plusieurs notions: Les attributs : Il s'agit des données caractérisant l'objet. Ce sont des variables stockant des informations d'état de l'objet. Les méthodes (appelées parfois fonctions membres) : Les méthodes d'un objet caractérisent son comportement, c'est-à-dire l'ensemble des actions (appelées opérations) que l'objet peut réaliser. Ces opérations permettent de faire réagir l'objet selon des invocations extérieures (ou d'agir sur les autres objets). De plus, les opérations sont fortement liées aux 35 Chapitre II : Programmation Orientée Objet : Concepts de base attributs, car leurs actions peuvent dépendre des valeurs des attributs, ou bien peuvent les modifier. L'identité : L'objet possède une identité qui permet de le distinguer des autres objets, indépendamment de son état. On construit généralement cette identité grâce à un identifiant découlant naturellement du problème (par exemple un produit pourra être repéré par un code, une voiture par un matricule, ...). 3. La notion de classe On appelle classe la définition de la structure d'un objet, c'està-dire la déclaration de l'ensemble des objets qui ont des mêmes caractéristiques. En réalité, on dit qu'un objet est une instanciation d'une classe. On parle donc d'objet ou d'instance (éventuellement d'occurrence). Une classe est composée de deux parties: Les attributs (parfois appelés données membres) : il s'agit des données représentant l'état de l'objet. Les méthodes (parfois appelées fonctions membres) : il s'agit des opérations applicables aux objets. Si on définit la classe voiture, les objets Peugeot 406, Renault 18 seront des instanciations de cette classe. 36 Chapitre II : Programmation Orientée Objet : Concepts de base Objets bicyclettes Classe bicyclette Bicyclette Abstraction Taille de cadre Taille de roues Vitesse Conduire Objets polygones Attributs Méthodes Classe polygone Polygone Abstraction Arrête Couleur de fond Dessiner Attributs Méthodes Figure II.13: Abstraction de quelques objets du monde réel 4. Héritage 4.1. La notion d'héritage L'héritage est un principe propre à la programmation orientée objet, permettant de créer une nouvelle classe à partir d'une classe existante. Le nom "héritage" provient du fait que la classe dérivée (la nouvelle classe) contient les attributs et les méthodes de sa superclasse (la classe existante). Cela permet de définir de nouveaux attributs et de nouvelles méthodes pour la classe dérivée, qui viennent s'ajouter à ceux et celles héritées. 4.2. Hiérarchie de classes Il est possible de représenter sous forme d’hiérarchie de classes, parfois appelée arborescence de classes, la relation d’héritage qui existe entre les différentes classes. L'arborescence commence par une classe générale appelée superclasse (classe mère). Puis les classes dérivées (classe fils ou sous-classes) deviennent de plus en plus spécialisées. Ainsi, on peut généralement exprimer la relation qui lie une 37 Chapitre II : Programmation Orientée Objet : Concepts de base classe fils à sa classe mère par la phrase "est un" (en anglais "is a"). Animal Herbivore Carnivore Omnivore Lapin Lion Tigre Figure II.24: Exemple de diagramme de classe 4.3. Héritage multiple L’héritage multiple offre la possibilité de faire hériter une classe de deux superclasses. Ainsi, cette technique permet de regrouper au sein d'une seule et même classe, les attributs et méthodes de plusieurs classes. Animal Herbivore Carnivore Omnivore Figure II.35: Exemple d’héritage multiple 5. Encapsulation 5.1. Le concept d'encapsulation L'encapsulation est un mécanisme consistant à rassembler les données et les méthodes au sein d'une structure en cachant l'implémentation de l'objet, c'est-à-dire en empêchant l'accès aux données par un autre moyen que les méthodes proposées. L'encapsulation permet donc de garantir l'intégrité des données contenues dans l'objet. 38 Chapitre II : Programmation Orientée Objet : Concepts de base 5.2. Niveaux de visibilité L'encapsulation permet de définir des niveaux de visibilité des éléments de la classe. Ces niveaux de visibilité définissent les droits d'accès aux données. Il existe trois niveaux de visibilité: Publique : les fonctions de toutes les classes peuvent accéder aux données ou aux méthodes d'une classe définie avec le niveau de visibilité public. Il s'agit du plus bas niveau de protection des données. Protégée : l'accès aux données est réservé aux fonctions des classes héritières, c'est-à-dire par les fonctions membres de la classe, ainsi que les fonctions des classes dérivées. Privée : l'accès aux données est limité aux méthodes de la classe elle-même. Il s'agit du niveau de protection des données le plus élevé. 6. Polymorphisme 6.1. Définition du polymorphisme Le nom polymorphisme vient du grec et signifie qu’une chose peut prendre plusieurs formes. C’est une caractéristique essentielle de la programmation orientée objet. On distingue généralement trois types de polymorphisme : Le polymorphisme ad hoc (ou surcharge ; en anglais overloading). Le polymorphisme d'héritage (ou redéfinition ou encore spécialisation ; en anglais overriding). Le polymorphisme paramétrique (ou généricité ; en anglais template). 6.2. Types de polymorphisme Nous allons maintenant tenter de définir plus précisément tout cela, mais il est important de noter que beaucoup de confusions existent lorsqu'il s'agit de différencier tous ces types de polymorphisme. 39 Chapitre II : Programmation Orientée Objet : Concepts de base 6.2.1. Le polymorphisme ad hoc Le polymorphisme ad hoc permet d'avoir des fonctions de même nom, avec des fonctionnalités similaires, dans des classes qui n’ont aucun rapport entre elles. Par exemple, la classe complexe, la classe image et la classe lien peuvent avoir chacune une fonction "afficher". Cela permettra de ne pas avoir à se soucier du type de l'objet que l'on a, si on souhaite l'afficher à l'écran. 6.2.2. Le polymorphisme d'héritage Le polymorphisme d’héritage permet de redéfinir une méthode dans des classes héritant d'une superclasse. Imaginons un jeu d'échec comportant des objets roi, reine, fou, cavalier, tour et pion, héritant chacun de l'objet pièce. La méthode mouvement() pourra, grâce au polymorphisme d'héritage, effectuer le mouvement approprié en fonction de la classe de l'objet référencé au moment de l'appel. 6.2.3. Le polymorphisme paramétrique Le polymorphisme paramétrique permet de définir plusieurs fonctions de même nom, mais possédant des paramètres différents (en nombre et/ou en type). On peut par exemple définir plusieurs méthodes homonymes addition() effectuant une somme de valeurs. La méthode int addition(int, int) pourra retourner la somme de deux entiers. La méthode float addition(float, float) pourra retourner la somme de deux flottants. La méthode char addition(char, char) pourra définir la concaténation de deux caractères. etc. On appelle signature le nombre et le type des arguments d'une fonction. C'est donc la signature d'une méthode qui détermine quelle méthode sera appelée. 40 Chapitre III : La Programmation Orientée Objet en Java Chapitre III : La Programmation Orientée Objet en Java 1. Introduction La programmation orientée objet permet de mettre en œuvre des programmes organisés en ensembles d’objets coopérants. Chacun représente une instance d’une certaine classe. 2. Classes et Objets L’écriture d’un programme Java consiste à écrire un ensemble de classes comportant des attributs et des méthodes qui peuvent instancier des objets d’autres classes et appeler leurs méthodes. Dans ce qui suit, nous allons expliquer la notion de classe et d’objet en Java. 2.1. Classe La définition d’un nouveau type de données, d’une façon générale, se fait en Java en utilisant les classes. Une classe comporte des attributs et des méthodes. En Java, on ne peut écrire des algorithmes que comme méthodes d’une classe. On peut dire que : Classe = attributs + Méthodes. Pour définir la classe Triangle avec 2 attributs et une méthode surface(), on peut écrire : class Triangle { // Attributs de la classe double hauteur ; // hauteur du triangle double base ; // base du triangle // Méthode calculant la surface du triangle double surface() { return base * hauteur / 2 ; } } 41 Chapitre III : La Programmation Orientée Objet en Java 2.2. Objet Pour instancier un objet d’une classe, on fait un appel explicite à l’opérateur new en précisant la classe à instancier. Un objet est donc une instance d’une classe. Format général : <nomClasse>() ; <nomClasse> reference = new L’appel de new a deux effets : Il crée un objet de type <nomClasse>. Il retourne la référence (adresse) de cet objet. Cette référence doit être mémorisée dans une variable (reference) pour pouvoir accéder à l’objet créé. Pour créer un objet Triangle on met : Triangle t ; // Déclaration d’une variable t t = new Triangle (); // Création d’un objet Triangle Il est possible de mettre directement : Triangle t = new Triangle (); L’accès à un élément (attribut ou méthode) se fait en écrivant le nom de la référence à côté du nom de l’élément, séparés par un point. Pour initialiser l’objet t créé au-dessus avec une hauteur 3 et une base 4, on peut écrire : t.hauteur = 3 ; t.base = 4 ; // Accès aux attributs via la référence Remarque : dans la littérature, le concept objet est souvent utilisé avec une ambiguïté. Il est utilisé pour indiquer une instance, ou bien pour indiquer la classe elle-même. Dans ce cours, on utilise le concept objet pour indiquer l’instance. 2.3. Constructeur de la classe En Java, vous pouvez écrire au sein d’une classe des constructeurs, prenant éventuellement des paramètres d’entrée, et initialisant l’objet lors de sa création. Le constructeur est alors automatiquement appelé par l’opérateur new quand vous instanciez un nouvel objet de la classe. Le constructeur d’une classe ressemble à une méthode, sans sortie, sans type, et qui a le même nom que la classe. Ainsi, un 42 Chapitre III : La Programmation Orientée Objet en Java constructeur de Triangle, prenant en entrées la base et la hauteur, s’écrit dans la classe comme suit : class Triangle { …. Triangle (double h, double b) //Constructeur de la classe Triangle { hauteur = h ; base = b ; } …. } Avec le constructeur au-dessus, il est possible de créer un objet et de l’initialiser de manière très compacte: Triangle t = new Triangle (3,4); Si la classe Triangle est déclarée sans aucun constructeur, alors elle possède implicitement le constructeur suivant : Triangle () { } Il est aussi appelé constructeur par défaut. 3. Construction d’un programme Java Un programme Java est un ensemble d’objets qui se demandent des services en appelant leurs méthodes. La seule exception est les types de base (prédéfinis), pour lesquels une variable détient directement sa valeur et n’est pas une référence à un objet. Un programme Java est enfin de compte une classe qui peut faire appel à d’autres classes. Pour voir son exécution, le programme Java doit disposer d’une méthode main qui constitue son point d’entrée. Reprenons la classe Triangle précédente définie comme suit : class Triangle { double hauteur ; double base ; Triangle (double x, double y) { 43 Chapitre III : La Programmation Orientée Objet en Java hauteur = x ; base = y ; } double surface() { return base * hauteur / 2 ; } } Après avoir compilé la classe Triangle précédente, et dans le même répertoire, nous allons écrire le programme Java Triangle_Calcul comme suit : class Triangle_Calcul { public static void main (String [] args) { Triangle t = new Triangle(3,9); System.out.println("Avec h = " + t.hauteur + " et b = "+ t.base +" Surface = " + t.surface()); } } Le programme Java au-dessus affiche : Avec h = 3.0 et b = 9.0 Surface = 13.5 Il est possible de définir un programme Java qui fait appel à une classe interne et une autre externe comme c’est le cas dans l’exemple suivant : class TriangleRectangle_Calcul { static class Rectangle { double longueur ; double largeur ; Rectangle (double x, double y) { longueur = x ; largeur = y ; } double surfaceR() { return longueur * largeur ; } } public static void main (String [] args) 44 Chapitre III : La Programmation Orientée Objet en Java { Triangle t = new Triangle(3,9); System.out.println("SurfaceT = " + t.surface()); Rectangle r = new Rectangle(4,33); System.out.println("SurfaceR = " + r.surfaceR()); } } Le programme Java affiche : SurfaceT = 13.5 SurfaceR = 132.0 Constatez que la classe Rectangle est précédée par le mot clé static dont on va expliquer plus tard. 4. Classes imbriquées On a vu au-dessus un programme Java, qui est enfin de compte une classe, faisant appel à une classe interne. C’est un cas particulier des classes imbriquées. Plus généralement, on peut dire qu’une classe peut être un attribut dans une autre classe. Définissons par exemple la classe TriangleRectangle comme suit : class TriangleRectangle { double hauteur ; double base ; class Rectangle { double longueur ; double largeur ; Rectangle (double a, double b) { longueur = a ; largeur = b ; } double surface() { return longueur * largeur ; } } TriangleRectangle (double x, double y) 45 Chapitre III : La Programmation Orientée Objet en Java { hauteur = x ; base = y ; } double surfaceT() { return base * hauteur / 2 ; } double surfaceR(double z, double h) { Rectangle r = new Rectangle(z,h); return r.surface() ; } } Après avoir compilé la classe TriangleRectangle, on définit dans le même répertoire le programme Java suivant : class TriangleRectangle_Calcul2 { public static void main (String [] args) { TriangleRectangle tr = new TriangleRectangle(9,3); System.out.println("SurfaceT = " + tr.surfaceT()); System.out.println("SurfaceR = " + tr.surfaceR(4,33)); } } Le programme Java au-dessus affiche : SurfaceT = 13.5 SurfaceR = 132.0 5. Héritage en Java Java permet de définir la relation d’héritage entre les classes. Soit par exemple la classe Triangle définie comme suit : class Triangle { double hauteur ; double base ; Triangle (double x, double y) { hauteur = x ; base = y ; } 46 Chapitre III : La Programmation Orientée Objet en Java double surface() { return base * hauteur / 2 ; } } Il est donc possible de définir la classe TriangleMMSS héritant la classe Triangle en utilisant le mot clé extends, et cela comme suit : class TriangleMMSS extends Triangle { double TTDD ; TriangleMMSS (double x, double y, double z) { super(x , y) ; TTDD = z ; } double perimetre () { return base + TTDD * 2 ; } } Remarques : La classe TriangleMMSS a hérité implicitement les attributs hauteur et base, ainsi que la méthode surface() de la classe mère Triangle. On commence généralement le constructeur d’une sous-classe par un appel du constructeur de sa classe mère. Cela se fait par l’instruction super(). On passe à super() les paramètres nécessaires à l’appel du constructeur de la classe mère. En général, ces paramètres constituent un sous-ensemble des paramètres du constructeur de la sous-classe. Si le constructeur de la classe mère d’une classe n’est pas appelé explicitement, c’est le constructeur sans aucun paramètre qui est appelé (constructeur par défaut). Il est possible de définir des méthodes abstraites, par le mot clé abstract, d’une classe générique. Cela implique que toutes les classes qui héritent de cette classe générique devront spécifier concrètement ces méthodes. Une classe peut être aussi définie comme abstraite ; dans ce cas elle ne peut être que héritée et 47 Chapitre III : La Programmation Orientée Objet en Java non pas instanciée. En pratique, toute classe qui possède au moins une méthode abstraite est considérée comme abstraite, même si elle n’est pas déclarée comme telle. Le compilateur refuse tout appel du constructeur sur une telle classe (Voir Exercice 4, Série 2 : Gestion d’une collection d’objets). Soit maintenant le programme Java suivant : class TriangleMMSS_Affiche { public static void main (String [] args) { TriangleMMSS t = new TriangleMMSS(9,3, 9.12); System.out.println("Surface = " + t.surface()); System.out.println("Perimetre = " + t.perimetre()); } } Le programme Java au-dessus affiche : Surface = 13.5 Perimetre = 21.24 6. L’encapsulation en Java Java permet de définir des droits d’accès sur les éléments (attributs et méthodes) d’une classe par les mots clés suivants : public : les éléments publics sont accessibles sans aucune restriction. Les éléments publics d’une classe sont hérités par ses sous-classes. protected : les éléments protégés ne sont accessibles que depuis la classe elle-même, les sous-classes qui en héritent et les classes du même package. En Java, un package dénote un regroupement de classes. Notamment, les classes définies dans le même répertoire appartiennent au même package. private : les éléments privés ne sont accessibles que depuis la classe elle-même. Les éléments privés d’une classe ne sont pas hérités par ses sous-classes. 48 Chapitre III : La Programmation Orientée Objet en Java Si on ne précise pas le droit d’accès avant un élément alors il est considéré public. Soit par exemple la classe Triangle définie comme suit : class Triangle { protected double hauteur ; protected double base ; public double surface() { return base * hauteur / 2 ; } } On définit ensuite la classe TriangleMMSS comme suit : class TriangleMMSS extends Triangle { private double TTDD ; TriangleMMSS (double x, double y, double z) { hauteur = x ; base = y ; TTDD = z ; } public double perimetre () { return base + TTDD * 2 ; } } Soit le programme Java suivant : class TriangleMMSS_Affiche { public static void main (String [] args) { TriangleMMSS t = new TriangleMMSS(9,3, 9.12); System.out.println("Surface = " + t.surface()); System.out.println("Perimetre = " + t.perimetre()); } } Le programme affiche : Surface = 13.5 Perimetre = 21.24 49 Chapitre III : La Programmation Orientée Objet en Java Maintenant, si on modifie la classe Triangle comme suit : class Triangle { private double hauteur ; private double base ; public double surface() { return base * hauteur / 2 ; } } Alors la compilation de la classe TriangleMMSS va générer le message d’erreur : TriangleMMSS.java:6: hauteur has private access in Triangle hauteur = x ; ^ TriangleMMSS.java:7: base has private access in Triangle base = y ; ^ TriangleMMSS.java:12: base has private access in Triangle return base + TTDD * 2 ; ^ 3 errors C’est à dire que les éléments (les attributs base et hauteur) déclarés comme privés ne peuvent être utilisés que par la classe Triangle et non pas par la classe qui hérite (TriangleMMSS). Remarque : généralement, les attributs sont déclarés private et les méthodes sont déclarées public, permettant ainsi la manipulation des attributs de la classe. 7. Polymorphisme en Java On a dit qu’une classe peut posséder de zéro à plusieurs constructeurs. C’est lors de l’instanciation que le compilateur détermine le constructeur à utiliser. Par exemple, soit la classe Triangle définie comme suit : class Triangle { double hauteur = 5 ; double base = 2 ; Triangle (double x, double y) 50 Chapitre III : La Programmation Orientée Objet en Java { hauteur = x ; base = y ; } Triangle (double x) { hauteur = x ; } double surface() { return base * hauteur / 2 ; } } Et soit le programme Java suivant : class Triangle_Affiche { public static void main (String [] args) { Triangle t1 = new Triangle(9,3); System.out.println("Surface = " + t1.surface()); Triangle t2 = new Triangle(3); System.out.println("Surface = " + t2.surface()); } } Le programme Java au-dessus affiche : Surface = 13.5 Surface = 3.0 7.1. Polymorphisme paramétrique D’une façon plus générale, une classe peut posséder un ensemble de méthodes avec le même nom, mais avec un nombre différent de paramètres. C’est lors de l’appel que le compilateur détermine quelle méthode va exécuter. Soit par exemple la classe Triangle définie comme suit : class Triangle { double hauteur = 5 ; 51 Chapitre III : La Programmation Orientée Objet en Java double base = 2 ; double surface(double x, double y) { hauteur = x; base = y; return base * hauteur / 2 ; } double surface() { return base * hauteur / 2 ; } } Dans la classe Triangle on vient de définir la méthode surface() deux fois ; chacune avec un nombre différent de paramètres. On définit ensuite le programme Java comme suit : class Triangle_Affiche { public static void main (String [] args) { Triangle t1 = new Triangle(); System.out.println("Surface = " + t1.surface(9,3)); Triangle t2 = new Triangle(); System.out.println("Surface = " + t2.surface()); } } Le programme Java au-dessus affiche : Surface = 13.5 Surface = 5.0 Cet exemple reflète la notion de polymorphisme paramétrique qui permet de définir un ensemble de méthodes ayant le même nom mais avec des paramètres différents. 7.2. Polymorphisme d’héritage Dans ce qui suit nous allons voir un exemple de polymorphisme d’héritage qui consiste à redéfinir une méthode héritée d’une super-classe. Pour cela, on définit la classe Triangle comme suit : class Triangle 52 Chapitre III : La Programmation Orientée Objet en Java { double hauteur ; double base ; Triangle(double x, double y) { hauteur = x ; base = y ; } double surface() { return base * hauteur / 2 ; } } On définit ensuite la classe TriangleMMSS comme suit : class TriangleMMSS extends Triangle { double TTDD ; TriangleMMSS (double x, double y) { super(x, y) ; } double perimetre () { return base + TTDD * 2 ; } double surface () { TTDD = 9.12 ; return base * hauteur / 2 ; } } Remarques : Dans la classe TriangleMMSS, on vient de redéfinir la méthode surface() héritée de la classe mère Triangle. Il était possible de redéfinir la classe surface() comme suit : class TriangleMMSS extends Triangle { double TTDD ; TriangleMMSS (double x, double y) { super(x, y) ; 53 Chapitre III : La Programmation Orientée Objet en Java } double perimetre () { return base + TTDD * 2 ; } double surface () { TTDD = 9.12 ; return super.surface() ; } } Le mot-clé super permet de désigner l’objet père de l’objet courant. Il est donc utilisé pour appeler une méthode d’un objet de la classe mère lorsqu’elle n’a pas la même définition au niveau de la sous-classe. Enfin, on définit le programme Java suivant : class TriangleMMSS_Affiche { public static void main (String [] args) { TriangleMMSS t = new TriangleMMSS(9,3); System.out.println("Surface = " + t.surface()); System.out.println("Perimetre = " + t.perimetre()); System.out.println("TTDD = " + t.TTDD); } } Le programme Java au-dessus affiche : Surface = 13.5 Perimetre = 21.24 TTDD = 9.12 7.3. Polymorphisme ad hoc Maintenant, nous allons voir un exemple de polymorphisme ad hoc qui consiste à définir des méthodes de même nom, avec des fonctionnalités similaires, dans des classes indépendantes. Pour cela, on définit la classe Triangle comme suit : class Triangle { double hauteur ; double base ; 54 Chapitre III : La Programmation Orientée Objet en Java Triangle (double x, double y) { hauteur = x ; base = y ; } double surface() { return base * hauteur / 2 ; } } On définit ensuite la classe Rectangle comme suit : class Rectangle { double longueur ; double largeur ; Rectangle (double x, double y) { longueur = x ; largeur = y ; } double surface() { return longueur * largeur ; } } Remarquez qu’on a repris la fonction surface(), déjà définie dans la classe Triangle, dans la classe Rectangle, mais avec un code différent. Soit le programme Java suivant : class TriangleRectangle_Calcul { public static void main (String [] args) { Triangle t = new Triangle(9,3); System.out.println("SurfaceT = " + t.surface()); Rectangle r = new Rectangle(4,33); System.out.println("SurfaceR = " + r.surface()); } } Le programme au-dessus affiche : 55 Chapitre III : La Programmation Orientée Objet en Java SurfaceT = 13.5 SurfaceR = 132.0 8. Le mot clé static Le mot clé static peut précéder aussi bien des attributs que des méthodes définis dans une classe. 8.1. Les attributs statiques Quand on crée plusieurs instances (objets) d’une même classe, chaque instance possède ses propres valeurs pour chacun de ses attributs. Dans le cas des attributs statiques (précédés par le mot clé static), il n’existe qu’une seule copie de l’attribut dans la mémoire pour tous les objets de la classe : l’attribut est rattaché à la classe elle-même et non pas à ses instances. Par conséquent, tous les objets partagent la même valeur pour l’attribut, et si un seul objet modifie cette valeur, elle sera modifiée pour tous les objets de cette classe. L’exemple suivant décrit le fonctionnement du mot clé static. On définit alors la classe Triangle comme suit : class Triangle { static double hauteur ; double base ; Triangle (double x, double y) { hauteur = x ; base = y ; } double surface() { return base * hauteur / 2 ; } } Ensuite, on définit le programme Java suivant : class Triangle_Affiche { public static void main (String [] args) { Triangle t1 = new Triangle(9,3); 56 Chapitre III : La Programmation Orientée Objet en Java System.out.println("Avec h = " + t1.hauteur + " et b = "+ t1.base +" Surface = " + t1.surface()); Triangle t2 = new Triangle(4,6); System.out.println("Avec h = " + t1.hauteur + " et b = "+ t1.base +" Surface = " + t1.surface()); System.out.println("Avec h = " + t2.hauteur + " et b = "+ t2.base +" Surface = " + t2.surface()); } } Le programme Java au-dessus affiche : Avec h = 9.0 et b = 3.0 Surface = 13.5 Avec h = 4.0 et b = 3.0 Surface = 6.0 Avec h = 4.0 et b = 6.0 Surface = 12.0 Comme vous remarquez, la création de la deuxième instance t2 a influé sur la valeur de l’attribut hauteur de la première instance t1, et non pas sur l’attribut base, car l’attribut hauteur est déclaré comme static à l’inverse de l’attribut base. Le changement de la valeur de l’attribut hauteur a provoqué le changement de calcul de la surface. 8.2. Les méthodes statiques Le mot clé static peut aussi précéder une méthode. Les méthodes statiques vérifient le même principe que les attributs statiques. Il n’en existe qu’une seule copie par classe, c’est une méthode de la classe plutôt que de ses instances. Par construction, une méthode statique ne peut avoir accès qu’aux éléments (attributs et méthodes) statiques d’une classe. Pour appeler une méthode statique d’une classe, on utilise en général le nom de la classe plutôt qu’une de ses instances. Cela évite d’avoir à appeler le constructeur de la classe et de construire une instance. L’intérêt des méthodes statiques est en effet de pouvoir être appelées alors qu’on ne dispose pas d’un objet de la classe dans laquelle elle est définie. Soit par exemple la classe Triangle définie comme suit : class Triangle { static double hauteur ; static double base ; 57 Chapitre III : La Programmation Orientée Objet en Java Triangle () { } static double surface(double x, double y) { hauteur = x ; base = y ; return base * hauteur / 2 ; } } On définit le programme Java suivant : class Triangle_Affiche { public static void main (String [] args) { System.out.println("Surface = " + Triangle.surface(9,3)); } } Le programme Java au-dessus affiche : Surface = 13.5 Remarquez bien qu’on a évité de mettre : class Triangle_Affiche { public static void main (String [] args) { Triangle t = new Triangle(); System.out.println(" Surface = " + t.surface(9,3)); } } La méthode main() est statique ; c’est donc une méthode de la classe qui la contient plutôt que celle des objets de cette classe. Le paramètre de la fonction main() est un tableau de chaînes de caractères qui représente les chaînes de caractères passées en argument dans la ligne de commande. 58 Chapitre III : La Programmation Orientée Objet en Java 8.3. Le mot clé final Le mot clé static a le même rôle que le mot clé final utilisé pour la définition des attributs constants. La différence est que pour un constant, la copie de l’attribut est dupliquée autant de fois qu’une nouvelle instance est créée. Pour une optimisation d’espace, le mot clé final est souvent utilisé avec le mot clé static pour déclarer un attribut constant, par exemple : public static final int x = 7 ; Dans le cas d’une méthode, final indique que les classes qui héritent de la classe dans laquelle cette méthode est définie ne peuvent pas redéfinir cette méthode. Les sous-classes doivent utiliser cette méthode telle qu’elle est. 9. Cycle de vie d’un objet On appelle cycle de vie d’un objet l’ensemble des états par lesquels il passe au cours d’exécution d’un programme. En général, les étapes de vie d’un objet sont sa construction, son initialisation, parfois sa modification ou sa copie, puis sa destruction. 9.1. Allocation en mémoire et construction des objets La déclaration d’une variable se traduit par la réservation d’un emplacement mémoire qui sert à stocker la valeur de cette variable. Par exemple, l’instruction int a = 1 ; réserve un emplacement mémoire de taille suffisante pour stocker un entier, puis dépose la valeur 1 dans cet emplacement mémoire. Le mécanisme est le même pour tous les types de base. Qu’en est-il pour les objets ? La déclaration d’un objet T de type Triangle se passe en deux étapes : 1. Triangle T ; cette instruction réserve un emplacement mémoire pour une référence sur un objet de type Triangle, c’est à dire une variable dont la valeur est l’adresse d’un objet de type Triangle. 2. T = new Triangle() ; cette instruction alloue (et initialise selon le constructeur) l’emplacement mémoire pour un 59 Chapitre III : La Programmation Orientée Objet en Java objet de type Triangle, en appelant un constructeur de la classe Triangle. C’est donc l’instruction new qui alloue l’espace mémoire, et renvoie l’adresse de l’espace alloué à la référence sur l’objet. Cela peut être représenté comme suit : Triangle T Objet de type Triangle alloué avec new Figure III.16: Représentation en mémoire d’une instanciation 9.2. Le mot clé this Le mot clé this contient la référence à l'objet actuel. Le paramètre (mot clé) this est implicitement présent dans chaque objet instancié. Soit par exemple la classe Triangle définie comme suit : class Triangle { double hauteur ; double base ; Triangle (double hauteur, double base) { this.hauteur = hauteur ; this.base = base ; } double surface() { return base * hauteur / 2 ; } } Dans le constructeur de la classe on a this.hauteur indique l’attribut hauteur de l’objet courant, par contre hauteur (à droite de l’affectation) correspond au paramètre du constructeur. De même que pour this.base et base. 60 Chapitre III : La Programmation Orientée Objet en Java 9.3. Libération de l’espace mémoire Nous avons montré comment un programme Java manipule des références sur des emplacements mémoire dans lesquels sont stockés des objets. Tous ces objets sont construits par une allocation dynamique en invoquant l’instruction new. Se pose alors le problème de la libération de la mémoire ainsi allouée. En Java l’outil qui s’occupe de la libération automatique de l’espace mémoire s’appelle le "garbage collector", que l’on traduit en français par "ramasse-miettes". 10. Exercices 10.1. Série 1 : Calcul des impôts locaux Dans le cadre de l’informatisation d’une mairie, on veut automatiser le calcul des impôts locaux. On distingue deux catégories d’habitation : les habitations à usage professionnel et les maisons individuelles, l’impôt se calculant différemment selon le type d’habitation. Pour cela, on définit les classes HabitationProfessionnelle et HabitationIndividuelle et les caractéristiques communes à ces deux classes sont regroupées dans la classe Habitation. On a donc un schéma de classes où les classes HabitationProfessionnelle et HabitationIndividuelle héritent de la classe Habitation. L’objectif de cette série d’exercices est d’implémenter ce schéma d’héritage et de mettre en œuvre le mécanisme de liaison dynamique. Exercice 1 : Définition de la classe Habitation. Objectif : Définir une classe avec un constructeur et créer une instance de cette classe. La classe Habitation comprend les attributs : proprietaire de type chaîne de caractères, et qui correspond au nom du propriétaire. adresse de type chaîne de caractères, et qui correspond à l’adresse de l’habitation. 61 Chapitre III : La Programmation Orientée Objet en Java surface de type double, et qui correspond à la surface de l’habitation donnée en m2 et qui permet de calculer le montant de l’impôt. Les méthodes : double Impot() qui permet de calculer le montant de l’impôt que doit payer le propriétaire de l’habitation à raison de 2 DA par m2. void Affiche() qui permet d’afficher les trois attributs de la classe Habitation. Un constructeur à trois paramètres permettant d’initialiser une instance de la classe Habitation : Habitation(String P, String A, double S); Question 1 : Définissez la classe Habitation. Question 2 : Tester votre programme avec le code donné comme suit : // Classe TestHabitation permettant de tester la classe Habitation class TestHabitation{ public static void main (String[] args){ double I; // création d'un objet de type Habitation Habitation H = new Habitation("Ahmed", "Oran", 120); // calcul de l'impôt I = H.Impot(); // affichage des attributs de la classe Habitation H.Affiche(); // affichage de l'impôt System.out.println("Impôt = " + I + " DA"); } } Le programme doit afficher : Propriétaire : Ahmed Adresse : Oran Surface : 120.0 Impôt = 240.0 DA Exercice 2 : Définition des classes HabitationIndividuelle et HabitationProfessionnelle. Objectif : Utiliser l’héritage pour définir de nouvelles classes, redéfinir des méthodes dans les classes héritières. 62 Chapitre III : La Programmation Orientée Objet en Java 1. Le calcul de l’impôt d’une maison individuelle est différent de celui d’une habitation, il se calcule en fonction de la surface habitable, du nombre de pièces et de la présence ou non d’une piscine. On compte 100 DA supplémentaires par pièce et 500 DA supplémentaires en cas de présence d’une piscine. Question 1 : Définir la classe HabitationIndividuelle qui hérite de la classe Habitation en utilisant l’en-tête suivant : class HabitationIndividuelle extends Habitation { ... } Ajouter les attributs NbPieces de type entier et Piscine de type booléen. Redéfinir les méthodes Impot et Affiche. La méthode Affiche doit afficher les attributs proprietaire, adresse et surface de la classe Habitation, et les attributs NbPieces et Piscine propres à la classe HabitationIndividuelle. La première ligne de la méthode Affiche commencera par l’instruction super.Affiche(), permettant d’appeler la méthode Affiche de la classe mère Habitation. Question 2 : Tester votre programme avec le code donné comme suit : // Classe TestHabitationIndividuelle pour tester la classe HabitationIndividuelle class TestHabitationIndividuelle{ public static void main (String [] args){ double I; // création d'un objet de type HabitationIndividuelle HabitationIndividuelle HI = new HabitationIndividuelle("Ahmed", "Oran", 120, 5, false); // calcul de l'impôt I = HI.Impot(); // affichage des attributs de la classe HabitationIndividuelle HI.Affiche(); // affichage de l'impôt System.out.println("Impôt = " + I + " DA"); } } Le programme doit afficher : Propriétaire : Ahmed Adresse : Oran Surface : 120.0 63 Chapitre III : La Programmation Orientée Objet en Java Nombre de pièces : 5 Existence d'une piscine : false Impôt = 740.0 DA 2. Le calcul de l’impôt d’une habitation à usage professionnel est également différent de celui d’une habitation. Il se calcule en fonction de la surface occupée par le bâtiment et du nombre d’employés travaillant dans l’entreprise. On compte 1000 DA supplémentaires par tranche de 10 employés. Question 3 : Définir la classe HabitationProfessionnelle qui hérite de la classe Habitation en utilisant l’en-tête suivant : class HabitationProfessionnelle extends Habitation { ... } Ajouter l’attribut NbEmployes de type entier. Redéfinir les méthodes Impot et Affiche. La méthode Affiche doit afficher, en plus des attributs proprietaire, adresse et surface, l’attribut NbEmployes. Question 4 : Tester votre programme à l’aide du code donné comme suit : // Classe TestHabitationProfessionnelle permettant de tester la classe HabitationProfessionnelle class TestHabitationProfessionnelle { public static void main (String [] args){ double I; // création d'un objet de type HabitationProfessionnelle HabitationProfessionnelle HP = new HabitationProfessionnelle("Ahmed", "Oran", 2500, 130); // calcul de l'impôt I = HP.Impot(); // affichage des attributs de la classe HabitationProfessionnelle HP.Affiche(); // affichage de l'impôt System.out.println("Impôt = " + I + " DA"); } } Le programme doit afficher : Propriétaire : Ahmed Adresse : Oran Surface : 2500.0 Nombre d'employés : 130 64 Chapitre III : La Programmation Orientée Objet en Java Impôt = 18000.0 DA Exercice 3 : Gestion des habitations d’une commune. Objectif : Mettre en œuvre le mécanisme de liaison dynamique. On désire à présent calculer l’impôt pour chacune des habitations (individuelles ou professionnelles) d’une commune. Pour cela, on utilise une collection d’objets représentée par un tableau de cinq éléments, où chaque élément désigne une habitation individuelle ou professionnelle. Question 1 : Ecrire le programme Java permettant de remplir le tableau avec les informations : ("Ahmed", "Oran", 2500, 130), ("Maamar", "Saida", 250, 10), ("Noureddine", "Saida", 100, 5, false), ("Mussa", "Alger", 1200, 90), ("Mohammed", "Naama", 130, 6, true), ensuite afficher les attributs de chaque élément du tableau ainsi que l'impôt correspondant à chacun. 10.2. Série 2 : Gestion d’une collection d’objets Exercice 1 : Définition de la classe Impair. Objectif : Créer une classe, et l’utiliser dans une fonction main. On souhaite afficher les 100 premiers entiers impairs. Pour préparer les exercices de cette série, on va le faire de façon un peu artificielle. On définira une classe Impair, qui représente les nombres impairs. La classe Impair possède les attributs suivants : ImpairCourant : un entier qui correspond au nombre impair courant. AppelPremier : un booléen qui indique qu’on vient juste d’appeler la méthode Premier() décrite cidessous. La classe Impair fournit aussi les méthodes suivantes : Impair() : le constructeur qui initialise AppelPremier à false. 65 Chapitre III : La Programmation Orientée Objet en Java int Premier() : retourne le premier des nombres impairs. int Suivant() : retourne le nombre impair suivant. La question c’est suivant quoi ? o Si on venait d’appeler la méthode Premier(), le suivant est le deuxième nombre impair. o Sinon, le suivant est le nombre impair qui suit celui qui a été retourné lors du dernier appel à la méthode Suivant(). boolean IlEnReste() : dit si, vu les appels précédents aux méthodes Premier() et Suivant(), on peut encore demander un autre nombre impair. Bien que la suite des nombres impairs soit infinie, nous avons choisi de la limiter aux 100 premiers nombres impairs. Donc la fonction IlEnReste() retourne false si on dépasse cette limite, true si on est encore en mesure de donner un Suivant() inférieur à cette limite. Question 1 : Une fois la classe Impair définie, écrivez une classe Main avec une fonction main, comme on le fait usuellement pour démarrer un calcul. Cette fonction main devra : Allouer (new) une instance de la classe Impair, que l’on appellera nb. Faire une boucle while qui traduit l’algorithme suivant : Tant qu’il reste des éléments à afficher dans nb, prendre l’élément suivant et l’afficher. Vous utiliserez les méthodes Premier(), Suivant() et IlEnReste() de l’objet nb. Exercice 2 : Définition de la classe Casier. Objectif : Cet exercice fait travailler la notion de tableau, de boucle, en plus des notions de l’exercice précédent. On souhaite définir une classe Casier qui permet de stocker 10 entiers, et de les récupérer en cas de besoin. Vous utiliserez un tableau Tiroir comme attribut dans la classe Casier. Les valeurs du tableau sont initialisées à zéro au niveau du constructeur. Pour stocker un entier k 66 Chapitre III : La Programmation Orientée Objet en Java dans la case i avec (0 <= i < 10), la classe Casier fournira la méthode : void Range(int k, // L’entier à ranger int i); // Le numéro du tiroir Pour avoir les entiers stockés, la classe Casier fournit les méthodes Premier(), Suivant(), IlEnReste() qui s’utilisent comme les méthodes de la classe Impair de l’exercice précédent. N’oubliez pas de définir aussi les attributs : NumTCourant qui indique le numéro du tiroir courant et AppelPremier qui indique que la méthode Premier() vient d’être appelée ou non. Faites apparaître proprement la taille maximale du tableau, de sorte à ne faire qu’une seule modification dans la classe Casier quand on veut la modifier par un attribut MaxT initialisé à dix. C’est le seul attribut déclaré public. Question 1 : Une fois la classe Casier définie, écrivez une classe Main avec une fonction main. Dans la fonction main de la classe Main, créez un casier par : Casier Cs = new Casier() ;. Remplir le tableau du casier par les valeurs que vous désirez en utilisant la méthode Range de l’objet Cs, et affichez l’ensemble du casier, de la même façon que vous aviez affiché les nombres impairs dans l’exercice précédent. Quand ça marche, ajoutez l’affichage de la somme des entiers du casier. Exercice 3 : Définition de la classe Syracuse. Objectif : Constructeur avec paramètre. Une suite de Syracuse se calcule comme suit. On se donne un entier de départ arbitraire, U(0). Pour un U(n) donné, on calcule U(n + 1) comme suit : Si U(n) est pair, U(n + 1) = U(n)/2, sinon U(n + 1) = 3 * U(n) + 1. Question 1 : Définissez une classe Syracuse dont le constructeur prend U0 en argument, et qui fonctionne à l’aide des fonctions Premier(), Suivant() et IlEnReste(). Cette classe fournit tour à tour les éléments de la suite de Syracuse commençant par le U0 passé au constructeur. On a constaté 67 Chapitre III : La Programmation Orientée Objet en Java (mais personne ne sait le montrer), que les suites de Syracuse finissent par avoir les valeurs : 4,2,1,4,2,1,4,2,1,…. On considérera qu’une fois qu’on a atteint la valeur 1, le calcul s’arrête. La méthode TermeSyracuse() est utilisée dans la classe Syracuse pour permettre de calculer et retourner le n+1ième terme du nième terme donné comme paramètre. Les attributs, TermeCourant qui correspond au terme actuel de la suite, TermeInitial qui correspond au premier terme de la suite et AppelPremier qui indique qu’on vient juste d’appeler la méthode Premier(), doivent apparaître dans la classe Syracuse. Question 2 : Dans une fonction main, définissez deux suites de Syracuse différentes (elles diffèrent par leur terme U0 qui doit être différent de 1), affichez-les, et calculez la somme des termes de la seconde suite. Exercice 4 : Définition de la classe Entiers. Objectif : Définir une classe de base abstraite avec des méthodes dont certaines sont abstraites et établir une relation d’héritage avec la classe Syracuse. On peut constater dans les deux derniers exercices, seules les méthodes Premier(), Suivant(), et IlEnReste() sont partagées entre plusieurs classes mais elles changent selon la classe qu’elle les possède. Question 1 : Définissez une classe Entiers qui impose l’existence des méthodes abstraites Premier(), Suivant() et IlEnReste(), et qui définit de plus une fonction d’affichage des entiers que fournit la classe par la méthode Affiche(), ainsi que le calcul de leur somme par la méthode Somme(). Question 2 : Réécrivez la classe Syracuse en la faisant hériter de Entiers. Ecrivez ensuite une fonction main, qui fait le même travail que celle de l’exercice précédent, mais cette fois-ci sans écrire de boucle. 68 Chapitre III : La Programmation Orientée Objet en Java 11. Correction des exercices 11.1. Série 1 : Calcul des impôts locaux Solution 1 : class Habitation { private String proprietaire ; private String adresse ; private double surface ; Habitation(String P, String A, double S) { proprietaire = P ; adresse = A ; surface = S ; } public double Impot() { return 2 * surface; } public void Affiche() { System.out.println("Propriétaire : " + proprietaire); System.out.println("Adresse : " + adresse); System.out.println("Surface : " + surface); } } Solution 2 : Définition de la classe HabitationIndividuelle : class HabitationIndividuelle extends Habitation { private int NbPieces ; private boolean Piscine ; HabitationIndividuelle(String P, String A, double S, int NP, boolean PS) { super(P,A,S); NbPieces = NP ; Piscine = PS ; } 69 Chapitre III : La Programmation Orientée Objet en Java public double Impot() { double Impt = super.Impot() + 100 * NbPieces; if (Piscine) Impt += 500; return Impt ; } public void Affiche() { super.Affiche(); System.out.println("Nombre de pièces : " + NbPieces); System.out.println("Existence d'une piscine : " + Piscine); } } Définition de la classe HabitationProfessionnelle : class HabitationProfessionnelle extends Habitation { private int NbEmployes ; HabitationProfessionnelle(String P, String A, double S, int NE) { super(P,A,S); NbEmployes = NE ; } public double Impot() { return super.Impot() + (NbEmployes/10) * 1000; } public void Affiche() { super.Affiche(); System.out.println("Nombre d'employés : " + NbEmployes); } } Solution 3 : // Définition de la classe TestCollection class TestCollection{ public static void main (String [] args){ Habitation [] TableauHabitation; // création d'un tableau contenant 5 habitations TableauHabitation = new Habitation [5]; // Initialisation des éléments du tableau 70 Chapitre III : La Programmation Orientée Objet en Java TableauHabitation[0] = new HabitationProfessionnelle("Ahmed", "Oran", 2500, 130); TableauHabitation[1] = new HabitationProfessionnelle("Maamar", "Saida", 250, 10); TableauHabitation[2] = new HabitationIndividuelle("Noureddine", "Saida", 100, 5, false); TableauHabitation[3] = new HabitationProfessionnelle("Mussa", "Alger", 1200, 90); TableauHabitation[4] = new HabitationIndividuelle("Mohammed", "Naama", 130, 6, true); // affichage des attributs de chaque élément du tableau ainsi que l'impôt correspondant for (int i = 0; i < 5; i++) { TableauHabitation[i].Affiche(); System.out.println("---> Impôt = " + TableauHabitation[i].Impot()); } } } 11.2. Série 2 : Gestion d’une collection d’objets Solution 1 : Définition de la classe Impair : class Impair { private int ImpairCourant; private boolean AppelPremier; Impair() { AppelPremier = false; } public int Premier() { ImpairCourant = 1; AppelPremier = true; return 1; } public int Suivant() { if (AppelPremier) { ImpairCourant = 3; AppelPremier = false; 71 Chapitre III : La Programmation Orientée Objet en Java return 3; } else { ImpairCourant+=2; return ImpairCourant; } } public boolean IlEnReste() { if (ImpairCourant < 99) return true; else return false; } } Définition de la classe Main : class Main { public static void main (String[]args) { Impair nb = new Impair(); System.out.println(nb.Premier()); while (nb.IlEnReste()) System.out.println(nb.Suivant()); } } Solution 2 : Définition de la classe Casier : class Casier { private int NumTCourant; private boolean AppelPremier; public int MaxT = 10; private int Tiroir [] = new int[MaxT] ; Casier() { AppelPremier = false; for (int i=0; i<MaxT; i++) Tiroir[i] = 0 ; } public int Premier() { NumTCourant = 0; AppelPremier = true; 72 Chapitre III : La Programmation Orientée Objet en Java return Tiroir[0]; } public int Suivant() { if (AppelPremier) { NumTCourant = 1; AppelPremier = false; return Tiroir[1]; } else { NumTCourant+=1; return Tiroir[NumTCourant]; } } public boolean IlEnReste() { if (NumTCourant < MaxT-1) return true; else return false; } public void Range(int k, int i) { if (i<MaxT)Tiroir[i] = k; else System.out.println("Indice hors de limites"); } } Définition de la classe Main : class Main { public static void main (String[]args) { Casier Cs = new Casier(); for (int i=0; i<Cs.MaxT; i++) Cs.Range(i*i,i); System.out.println(Cs.Premier()); while (Cs.IlEnReste()) System.out.println(Cs.Suivant()); int somme = Cs.Premier(); while (Cs.IlEnReste()) somme+=Cs.Suivant(); System.out.println("Somme = " + somme); } } Solution 3 : Définition de la classe Syracuse : 73 Chapitre III : La Programmation Orientée Objet en Java class Syracuse { private int TermeCourant; private int TermeInitial; private boolean AppelPremier; Syracuse(int U0) { TermeInitial = U0 ; AppelPremier = false; } public int Premier() { AppelPremier = true; TermeCourant = TermeInitial; return TermeInitial ; } public int Suivant() { if (AppelPremier) { TermeCourant = TermeSyracuse(TermeInitial); AppelPremier = false; return TermeCourant; } else { TermeCourant = TermeSyracuse(TermeCourant); return TermeCourant; } } public boolean IlEnReste() { if (TermeCourant != 1) return true; else return false; } public int TermeSyracuse(int Un) { if ((Un%2)==0) return Un/2; else return 3*Un + 1; } } Définition de la classe Main : class Main { public static void main (String[]args) { 74 Chapitre III : La Programmation Orientée Objet en Java System.out.println("Première suite : "); Syracuse Cr1 = new Syracuse(17); System.out.println(Cr1.Premier()); while (Cr1.IlEnReste()) System.out.println(Cr1.Suivant()); System.out.println("Deuxième suite : "); Syracuse Cr2 = new Syracuse(16); System.out.println(Cr2.Premier()); while (Cr2.IlEnReste()) System.out.println(Cr2.Suivant()); int somme = Cr2.Premier(); while (Cr2.IlEnReste()) somme+=Cr2.Suivant(); System.out.println("Somme de la deuxième suite = " + somme); } } Solution 4 : Définition de la classe Entiers : abstract class Entiers { abstract public int Premier(); abstract public int Suivant(); abstract public boolean IlEnReste(); public void Affiche () { System.out.println(Premier()); while (IlEnReste()) System.out.println(Suivant()); } public int Somme () { int somme = Premier(); while (IlEnReste()) somme+=Suivant(); return somme; } } Définition de la classe Syracuse : class Syracuse extends Entiers { private int TermeCourant; private int TermeInitial; private boolean AppelPremier; Syracuse(int U0) 75 Chapitre III : La Programmation Orientée Objet en Java { TermeInitial = U0 ; AppelPremier = false; } public int Premier() { AppelPremier = true; TermeCourant = TermeInitial; return TermeInitial ; } public int Suivant() { if (AppelPremier) { TermeCourant = TermeSyracuse(TermeInitial); AppelPremier = false; return TermeCourant; } else { TermeCourant = TermeSyracuse(TermeCourant); return TermeCourant; } } public boolean IlEnReste() { if (TermeCourant != 1) return true; else return false; } public int TermeSyracuse(int Un) { if ((Un%2)==0) return Un/2; else return 3*Un + 1; } } Définition de la classe Main : class Main { public static void main (String[]args) { System.out.println("Première suite : "); Syracuse Cr1 = new Syracuse(17); Cr1.Affiche(); System.out.println("Deuxième suite : "); 76 Chapitre III : La Programmation Orientée Objet en Java Syracuse Cr2 = new Syracuse(16); Cr2.Affiche(); System.out.println("Somme de la Cr2.Somme()); } } deuxième suite = " + Remarque : Il est possible de reprendre le même travail avec les classes : Casier et Impair. 77 Conclusion Générale La programmation classique sépare les données des traitements, rendant ainsi difficile la mise en place de contrôles, destinés à garantir la cohérence et l’intégrité des données. L’utilisateur peut en effet accéder directement aux données, sans utiliser les fonctions mises à sa disposition. La programmation orientée objet a été introduite afin de remédier à ces inconvénients en regroupant au sein d’une même unité, dite objet, les données et les traitements. En conclusion, la programmation orientée objet a deux avantages principaux: (1) contrôler l'accès aux données, et (2) permettre la modification des objets sans avoir d'incidence sur les programmes des utilisateurs. Java est un langage de programmation supportant les éléments de la programmation orientée objet. Dans ce support du cours nous avons présenté ce langage. Nous avons aussi présenté les notions de base de programmation orientée objet. Nous avons évidemment montré comment implémenter les notions orientées objet en Java. Nous espérons, avec ce support, doté l’étudiant d’un esprit orienté objet, et le mettre sur les railles pour la maîtrise du langage Java. Java met encore à la disposition des développeurs une API (Application Programming Interface) très riche, lui permettant de faire de très nombreuses choses. Ce langage propose à peu près tout ce dont on a besoin directement dans le JDK. De plus il existe d’autres API pour des fonctionnalités qui viendraient à manquer au JDK. En plus des API, la notion des Plugins (modules d’extension) offerte par les éditeurs Java, donnent à ce langage beaucoup d’avantages : rapidité, sécurité, fiabilité, portabilité, robustesse et richesse des API. Java, notamment via ses éditeurs Eclipse et NetBeans, offre des plugins intégrés, tels que ADT (Android Development 78 Tools), pour la programmation mobile. Java est le principal langage utilisé pour développer des applications pour le système d'exploitation libre Android de Google pour les appareils Mobiles. Nous espérons, dans le futur, préparer un support de cours sur la ″Programmation Mobile en Java″, destiné aux étudiants de la première année Master, 1ier semestre, Option : Systèmes d’information, au centre universitaire Salhi Ahmed de Naâma, Algerie. 79 Références bibliographiques additionnelles Vous pouvez lire encore : Chevallier, Robert. Java 9782326000230. 2013. 7. Edition : Pearson. ISBN : Delannoy, Claude. Exercices en Java : Java 5.0. Edition : Eyrolles. ISBN : 9782212133585. 2011. Delannoy, Claude. Programmer en Java. Edition : Eyrolles. ISBN : 9782212135664. 2012. Granet, Vincent. Algorithmique et programmation en Java : cours et exercices corrigés. Edition : Dunod. ISBN : 9782100712878. 2014. Groussard, Thierry. Java 7 : les bases du langage et de la programmation objet. Edition : ENI. ISBN : 9782746078246. 2013. Guérin, Brice-Arnaud. La programmation orientée objet avec C++. Edition : ENI. ISBN : 9782746073081. 2012. Kahloula, B. Programmer en JAVA. Edition : Pages bleues. ISBN : 978-9947-34-024-0. 2013. Laugié, Henri. Java et Eclipse : développez une application avec Java et Eclipse. Edition : ENI. ISBN : 9782746072350. 2012. Laugié, Henri. Java et NetBeans : développez une application avec Java et NetBeans. Edition : ENI. ISBN : 9782746075078. 2012. Tasso, Anne. Le livre de Java premier langage : avec 99 exercices corrigés. Edition : Eyrolles. ISBN : 9782212138542. 2013. 80 Annexe Le suivant est le programme officiel de la matière Programmation Orientée Objet, de la 2ième année Licence Informatique, Option : Systèmes Informatiques (SI), Semestre 3, issu du canevas proposé par le Comité Pédagogique National du Domaine mathématiques et informatique. Intitulé de la Matière : Programmation Orientée Objet (POO) Semestre : 3 Objectifs de l’enseignement : Ce cours a pour objectif l'introduction des concepts de base du langage Java. Il traite spécialement les thèmes tels que: Technologie orientée objet, encapsulation, héritage, polymorphisme, translation dynamique. Le cours développe les notions de base du langage en particulier: les classes, les objets, les constructeurs, les méthodes et les variables d'instances, les sous-classes, les interfaces et l'héritage multiple, les packages et la notion de visibilité en java, les méthodes et les variables de classe, et les classes abstraites. L'étudiant est censé avoir acquis les compétences suivantes : 1- L'essence de la programmation objet en java 2- Lire et comprendre des programmes en java 3- Ecrire la solution d'un problème en java 4- Ecrire des applications sophistiquées (utilisation de structures de données avancées) Connaissances préalables recommandées : Connaissance du langage C souhaitée Contenu de la matière : 1. Introduction à la Programmation Orienté Objet a. Notions de base b. Historique c. Utilisation des TAD 2. Les classes 81 a. Déclaration des classes b. Les constructeurs et destructeurs c. Les méthodes d’accès d. Encapsulation 3. Héritage et polymorphisme a. Généralités b. Surcharge et redéfinition c. Héritage : Références d. Polymorphisme e. Les classes abstraites 4. Interface et implémentation a. Principe b. Application 5. Interface graphique et Applet a. Composants, gestionnaire d’affichage b. Mise en page c. Gestion des événements et écouteur d. Applet Mode d’évaluation : Continu et Examen Références : 1. Le site officiel de Sun Microsystems : fr.sun.com/ 2. Le livre Penser Java : bruceeckel.developpez.com/livres/java/traduction/tij2/ 3. Conception objet en java avec bluej de david barnes. pearson education france 4. Java outside in de Bill Campbell. Cambridge University press 82 View publication stats