Java : Programmation Impérative Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Java : Programmation Impérative Résumé du cours précédent (I11) Paradigme impératif Algorithmique simple Découpage fonctionnel Qu’est-ce qu’ un programme informatique ? / un langage de programmation ? / un paradigme de programmation ? Le paradigme impératif instructions, séquence, états, variables d’état, affectation Algorithmique simple (Java noyau C) instructions de contrôle: tests (if, ?:, switch), boucles (for, while, do / break, continue, return), bloc d’instructions (simples, imbriqués) Types primitifs: noms, codage, opérateurs + librairie Math, typage fort, déclaration de variables, initialisation, constantes de type (2f, 0xA2, …) Tableaux de types simples: déclaration (types), initialisation (notation accolades), manipulation (notation crochets: itération, affectation, lecture) Chaînes de caractères (Java): String avec construction, déclaration et manipulations simples Fonctions: méthodes statiques, signature, paramètres formels, application, paramètres effectifs (passage par valeurs) Raffinement fonctionnel: granularité générale (modules, fonction, instruction, …), raffinement Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Qu’est-ce qu’un programme informatique ? Déf.1: un programme informatique est une séquence d'instructions sous forme compréhensible par l'ordinateur (dite binaire), décrivant une tâche à accomplir par celui-ci. [http://www.linux-france.org/article/kafkafr/node59.html] Déf.2: un programme informatique est une liste d'instructions, rédigée par un programmeur, sans laquelle un ordinateur ne saurait rien faire d'autre que rouiller. [http://rad2000.free.fr/glosntci.htm] Déf.3: un programme informatique est un ensemble d’instructions, rédigées pour qu’un ordinateur puisse, à l’aide de ses informations mémorisées, résoudre un problème donné. [Petit Robert] Mais, pour en donner une vision quelque peu concrète et usuelle, on peut voir un programme comme ce qui doit être exécuté par un ordinateur pour : soit transformer des données d’un état initial vers un état final, soit faire transiter des données d’un endroit à un autre, soit les deux à la fois. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Exemple de programme informatique Exemple de programme qui transforme des données d’un état initial vers un état final : un traitement de texte Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Qu’est-ce qu’un paradigme de programmation ? Déf.: Un paradigme de programmation est un style fondamental de programmation informatique qui traite de la manière dont les solutions aux problèmes doivent être formulées dans un langage de programmation (à comparer à la méthodologie, qui est une manière de résoudre des problèmes spécifiques de génie logiciel). [http://fr.wikipedia.org/wiki/Paradigme_%28programmation%29]. Un paradigme de programmation conditionne la vision que le développeur se fera de l’exécution de son programme. Il en existe de nombreux. Par exemple, les paradigmes : - Impératif, - Logique, - Fonctionnel, - Orientée Processus, - Orienté Objet, - Modèle/Vue/Contrôleur, Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Qu’est-ce qu’un paradigme de programmation ? Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Qu’est-ce qu’un paradigme de programmation ? - en programmation impérative, un programme est vu comme une suite ordonnée de transformations d’états, - en programmation fonctionnelle, un programme est vu comme une suite d'évaluations de fonctions sans états, - en programmation orientée objet, les développeurs doivent considérer le programme comme une collection d’objets en interaction, - en programmation logique, un programme est un ensemble de déclarations de faits et de règles qui concourent à représenter des connaissances et à les unifier pour répondre à des buts, - la programmation orientée processus permet aux développeurs de voir les applications comme des ensembles de processus agissant sur des états localement partagées. [wikipedia] En OO, chaque méthode doit être construite de sorte que l’état de l’objet reste cohérent à la sortie de la fonction. Ce n’est pas une obligation du raffinement fonctionnel. Aussi, dans d’autres langages, on trouve des fonctions qui ne respecte pas cet aspect essentiel pour la sécurité et la robustesse des programmes. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Qu’est-ce que le paradigme impératif ? Déf.: Le paradigme impératif est un paradigme de programmation qui repose sur trois notions principales que sont : celle de séquence d’instructions, de variables mutables, et d’affectation. instruction : « fais ceci » impérativement ! séquence d’instructions : « fais ceci ; puis fais cela ; etc. » variables mutables et affectations Dans les langages impératifs, les variables portent des états (valeurs) et une opération spéciale permet d’y écrire : l’affectation. Pour la lecture, une simple référence à la variable par son nom est équivalente à sa valeur (son état). Lorsqu’une variable ne peut être affectée qu’une seule fois, elle est dite « immutable » (constante), alors que lorsqu’elle peut être réaffectée autant de fois que nécessaire, elle devient « mutable ». Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
boucles (for / while / do) ou récursivité (appels récursifs) Algorithmique simple Qu’est-ce que l’algorithmique Déf.: L’algorithmique est l’ensemble des instructions permettant de réaliser un traitement recherché sur des données. En paradigme impératif, c’est une séquence d’instructions. Pour exprimer un algorithme, on utilise des instructions de contrôle de traitement de données : de tests : if / ?: / switch...case de boucles : for / while / do Ces seules instructions de contrôle permettent de résoudre tous les problèmes calculables (numériques comme symboliques). Les ensembles suivants d’instructions sont équivalents : boucles (for / while / do) ou récursivité (appels récursifs) Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Qu’est-ce que le découpage fonctionnel ? Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Qu’est-ce que le découpage fonctionnel ? Qu’est-ce que le découpage fonctionnel ? Déf.: Le découpage fonctionnel consiste à morceler un traitement en plusieurs parties fonctionnelles (ou méthodes en O-O). On peut vouloir découper un traitement pour deux raisons : diminuer sa longueur : quand un traitement est trop long (une page de code), on préfère le découper en traitements plus petits, qui seront alors invoqués séquentiellement. factoriser des parties : (c’est le cas le plus intéressant et le plus courant) il consiste à prévoir à l’avance et à extraire d’un traitement quelconque toutes les parties susceptibles d’être utilisées en d’autres endroits du programme (cela nécessite une certaine analyse). Exemples de factorisation : affichage des éléments d’un tableau / calcul de la longueur d’une chaîne / permutation dans un tableau / tri d’un tableau mais aussi chaque fonction mathématique représente une factorisation... Des deux types de découpage seul le second corresponde à ce qui est également appelé le raffinement fonctionnel. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Objectifs de ce cours (I21) Classes et objets simples Découpage structurel et fonctionnel Modularité fonctionnelle, robustesse et maintenance Classes et objets simples sans méthode Aspects dynamiques : le « garbage collector » Méthodes d’instance simples Connaissance de base de classes de l’API Java Méthodes d’instance spéciales Propriétés de classes : attributs et méthodes de classes Les tableaux d’objets versus les types ensemblistes ArrayList<E> et TreeMap<K,V> de Java Premiers éléments de conception logicielle La notion de package Prolongement : les classes comme types abstraits Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples : exemple Comment réaliser le clavier de cette calculatrice ? Il faudrait disposer de boutons tels que : chaque bouton soit différent des autres par : sa légende, sa couleur, sa position et sa taille... mais que tous possèdent : une légende, une couleur, des coordonnées, une largeur et une hauteur... On peut donc dire que tous les boutons ont des : caractéristiques communes mais que chacun a ses propres valeurs. Il en va de même pour tout ce qu’on a envie de nommer des objets au sens large du terme. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples : exemples (1) Classe BOUTON Tout ce qu’on a envie de nommer des objets au sens où cela possède des caractéristiques, peut être décrit par une entité générale que l’on nommera, en O-O, sa classe. Classe DOMINO Classe POISSON Classe PION Inversement, tout ce qui peut être décrit à l’aide d’une entité générale, ici une classe, peut permettre de générer autant d’objets, tous distincts par les valeurs de leurs attributs. Classe LIVRE Classe ACROBATIE Classe BILLET Classe LOTO Classe MAISON Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples : exemples (2) BOUTON Classe DOMINO Classe PION Objets BOUTON Objets DOMINO Objets PION 1 couleur 1 forme n trous 2 marques 1 couleur 1 forme 1 valeur Classes & Objets Objets POISSON Classe LOTO Classe POISSON Objets LOTO n lignes m colonnes n*m valeurs n*m positions Descripteurs des attributs des objets Instances particulières valuées 1 couleur 1 espèce 1 nourriture 1 objet = 1 instance de classe Classe BILLET Classe ACROBATIE Objets BILLET Classe LIVRE Un objet ACROBATIE 1 pays 1 valeur 1 nom de monnaie Objets LIVRE 1 nom de figure n acrobates 1 titre 1 auteur n pages Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples : code de classe (1) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Classes et objets simples : code de classe (1) Descripteurs des attributs des objets 1 objet = 1 instance de classe Instances particulières valuées Classes & Objets /** Classe représentant un domino * avec ses 2 marques. */ class Domino { // Attributs communs // à tous les objets // (données propres) int m1; // marque 1 int m2; // marque 2 // ...à suivre... } un domino (2,5) m1 = 2 m2 = 5 un domino (3,4) m1 = 3 m2 = 4 Insister sur le fait que les attributs ne sont pas déclarer statiquement dans la classe ! C’EST NOUVEAU ! un domino (2,5) m1 = 2 m2 = 5 un domino (6,6) m1 = 6 m2 = 6 Déclarations non statique Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Constructeur d’objets (détail 1) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Constructeur d’objets (détail 1) Pour disposer d’un objet, il faut le construire. Un constructeur porte le même nom que la classe et est généralement déclaré « public ». Il attend des paramètres qui permettront de construire un objet. /** Classe représentant un domino avec ses 2 marques. */ class Domino { // Attributs int m1; // marque 1 int m2; // marque 2 /** Le constructeur de domino */ public Domino (int vm1, int vm2){ // Instructions de construction // qui doivent affecter les marques // du domino en cours de construction // avec les valeurs des paramètres } La signature des construc-teurs est particulière : elle n’admet pas de type de retour ! L’expression en cours de construction est importante => cela permet de justifier intuitivement l’usage de this. Par rapport à la remarque d’absence de type de retour : cela est dû au fait que lorsqu’on construit un domino, on ne peut obtenir autre chose qu’un domino ! Java dispense de spécifier le type de retour des constructeurs. Déclaration « public » seulement et non plus « public static » ! Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Constructeur d’objets (détail 2) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Constructeur d’objets (détail 2) Dès l’entrée dans le constructeur, le futur objet a déjà un emplacement mémoire qui lui est réservé. Pour valuer l’objet, le constructeur doit donc référencer cet espace mémoire MAIS il ne le connaît pas directement ! Pour cela, Java lui fournit la variable spéciale « this » (dite d’auto-référencement). /** Classe représentant un domino avec ses 2 marques. */ class Domino { // Attributs int m1; // marque 1 int m2; // marque 2 /** Le constructeur de domino */ public Domino (int vm1, int vm2){ // Instructions d’initialisation // du domino en cours de construction this.m1 = vm1; // marque 1 this.m2 = vm2; // marque 2 } Moyennant l’usage de « this », le constructeur peut accéder aux attributs valués de l’objet en cours de construction. - L’expression EN COURS DE CONSTRUCTION est importante => cela permet de justifier intuitivement l’usage de THIS. Expliquer que la variable THIS est automatiquement mise à jour avec la référence de l’objet en cours de construction. En fait, dès qu’une ligne de code est exécutée relativement à l’objet concerné par l’exécution, la variable THIS correspond à l’AUTO-REFERENCE de cet objet. - Faire un schéma au tableau en montrant un espace mémoire où les attributs de l’objet apparaissent et où il apparaît d’autres dominos déjà construits auparavant. Le constructeur doit écrire dans cet espace mémoire. Il lui en faut donc l’adresse, c’est ce que contient THIS. - Parler aussi du passage de paramètres : les noms vm1 et vm2 sont arbitraires. Ils pourraient même être identiques à ceux des attributs du domino. Dans ce cas, ils les masquent (dernier déclaré, dernier visible) mais le fait d’écrire this.m1 = m1 serait correct car THIS réfère toujours aux attributs et non aux variables locales ! - Dire enfin que THIS est optionnel en réalité (implicite) MAIS que, dans un premier temps, il est demandé de l’écrire (explicitement). Nous ne pourrons utiliser les usages implicites du langage que lorsque leurs usages explicite sera acquis ! Notation pointée habituelle Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Constructeur d’objets (détail 3) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Constructeur d’objets (détail 3) /** Classe représentant un domino avec ses 2 marques. */ class Domino { // Attributs int m1; // marque 1 int m2; // marque 2 /** Constructeur avec 2 marques */ public Domino (int vm1, int vm2){ this.m1 = vm1; this.m2 = vm2; } /** Constructeur de domino double */ public Domino (int vm){ this.m1 = this.m2 = vm; /** Constructeur de domino par défaut */ public Domino (){ this.m1 = 0; this.m2 = 0; MAIS on peut aussi vouloir construire des dominos selon d’autres schémas. Par exemples : un domino double un domino par défaut. Parler de ce qui permet à Java de distinguer quel constructeur est invoqué entre les trois => il faut qu’il y ait une différenciation possible de la liste des paramètres (en type ou en nombre d’arguments). ICI, on dira qu’il y a SURCHARGE de constructeurs. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Construction d’objet : new Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Construction d’objet : new La classe étant maintenant finalisée, il ne reste qu’à construire des dominos ! Toute construction d’objet en Java doit être faite à l’aide de l’opérateur d’instanciation : new <Constructeur> (...paramètres...) qui retourne l’objet valide nouvellement construit. domino d1 m1 = 2 m2 = 5 domino d2 m1 = 3 m2 = 4 class MainDominos { /** Construction de dominos */ public static void main(String[] args) { Domino d1 = new Domino(2,5); Domino d2 = new Domino(3,4); Domino d3 = new Domino(6); Domino d4 = new Domino(2,5); // Faire quelque chose des dominos... if ( d4.m1!=d4.m2 ) d4.m1 = d4.m2; } domino d3 m1 = 6 m2 = 6 A remarquer : la classe et la méthode d’où sont construits les objets dominos: MainDominos et main la construction du double 6 les dominos d1 et d4 sont deux objets différents même s’ils ont les mêmes marques ! Commenter la dernière ligne : l’accès aux attributs des objets ne peut pas se faire à l’aide de THIS ici. Mais comme on dispose d’une référence sur les objets => c’est elle qu’il faut utiliser ! EN DETAILS DANS LE TRANSPARENT SUIVANT... domino d4 m1 = 2 m2 = 5 d1 et d4 sont des objets différents ! Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Accès aux attributs des objets : OID versus this Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Accès aux attributs des objets : OID versus this Domino d4 = new Domino(2,5); if ( d4.m1 != d4.m2 ) d4.m1 = d4.m2; En dehors de l’objet, on utilise l’objet Dans l’objet, on "est" l’objet classe MainDominos +$ Main(String[]) + = public $ = static La méthode main voit le domino au travers de sa référence ou OID. Ici, d4. Elle ne peut faire autrement que de l’utiliser car this n’a pas de sens pour le domino d4 dans main. Vision externe classe Domino m1 : int m2 : int +Domino(int,int) +Domino(int) +Domino() d4: Domino m1 = 2 m2 = 5 En NOTATION UML pour y habituer les étudiants (expliquer rapidement...) Commencer par la méthode main : on construit un domino / on garde sa référence d4 / on accède au domino avec d4 On est en vision EXTERNE : on est en dehors de l’objet On reprend la construction : à ce moment le constructeur est dans la classe Domino elle-même / il ne connaît pas d4 / il dispose de THIS. On est en vision INTERNE : effective que lorsque l’on est dans l’objet On peut ajouter que THIS dans la méthode main réfèrerait à un objet de classe MainDominos et non à un Domino ! MAIS ICI, ce n’est bien sûr pas le cas car main étant static, THIS n’est pas défini. this:Domino Vision interne this.m1 = vm1; this.m2 = vm2; Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples : VISION EXTERNE Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Classes et objets simples : VISION EXTERNE + = public $ = static Quand le code en cours d’exécution se trouve classe MainDominos +$ main(String[]) { Domino d2 = new Domino(3,4); Domino d4 = new Domino(2,5); if ( d4.m1 != d4.m2 ) d4.m1 = d4.m2; } EN DEHORS de la classe d’un OBJET : (i.e. en dehors de la classe qui représente l’objet) La VISION de l’objet est EXTERNE Le code en cours d’exécution accède à l’objet à l’aide d’une référence externe à l’objet (également appelée <OID>) d4 d2 Depuis une classe, pour accéder à un objet d’une autre classe, on doit utiliser une référence sur cet objet (OID). Un domino m1 = 2 m2 = 5 Un domino m1 = 3 m2 = 4 Vision externe Ex: Quand main() de MainDominos, désire accéder à un domino dont elle possède une référence, elle utilise cette référence pour spécifier le domino auquel elle veut accéder. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes et objets simples: VISION INTERNE Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 30/03/2017 Classes et objets simples: VISION INTERNE + = public Quand le code en cours d’exécution se trouve classe Domino m1 : int m2 : int +Domino(int vm1,int vm2){ this.m1 = vm1; this.m2 = vm2; } +Domino(int) +Domino() DANS la CLASSE d’un OBJET : (i.e. à l’intérieur de la classe qui représente l’objet) La VISION de l’objet est INTERNE On accède aux propriétés de l’objet en cours d’exécution à l’aide de la variable d’autoréférencement : this Depuis un constructeur, pour accéder à l’objet en cours de construction, on utilise THIS. Vision interne Ex: Dans un constructeur de Domino, le « domino en cours d’exécution » est celui « en cours de construction ». (bien que d’autres puissent avoir été construits antérieurement, c’est celui en cours de construction qui est référencé par this) Dominos déjà construits m1 = 3 m2 = 4 this:Domino m1 = ? m2 = ? Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Acta est fabula* * « La pièce est jouée. » On annonçait ainsi la fin de la représentation dans le théâtre antique. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde