Approche fonctionnelle Approche objet JAVA

Slides:



Advertisements
Présentations similaires
La programmation orientée objet avec Java L3-MIAGE Plan
Advertisements

Le mécanisme des exceptions
A propos de java Sun, fin 1995 C++ nettoyé semi-interprété
SI3 MAM3 Hydro Nathan Cohen Igor Litovsky Christophe Papazian
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Approfondissement du langage
(Classes prédéfinies – API Java)
C.
Programmer en JAVA par Tama
MIKHAYLOVA Vera Exposé Java principe de fonctionnement Lundi 17 mai 2004 DEUG 1ère année Science du langage Paris III.
TD 1 IJA Introduction Objet, méthode, attribut Classe, instance
1 Le mécanisme des exceptions Qu'est-ce qu'une exception? Comment définir et signaler des exceptions? Comment récupérer des exceptions?
Leçon 3 : Héritage IUP 2 Génie Informatique
Principes de programmation (suite)
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Langage Oriente Objet Cours 4.
Laboratoire d'Informatique de l’Université de Franche-Comté
Principes de programmation (suite)
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
© 2007 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java et les Exceptions Peter Van Roy Département dIngénierie Informatique,
Les Classes les structures en C (struct) regroupent des variables : structuration de l'analyse mais problèmes de cohérence problèmes de sécurité d'accès.
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Introduction à la programmation (Java)
Langage Oriente Objet Cours 2.
Les pointeurs Enormément utilisé en C/C++ ! Pourquoi? A quoi ça sert?
Structures de données IFT-2000
Introduction à la programmation objet Langage Java
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
Introduction au paradigme orienté-objet (suite)
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
Formation JAVA. Par: SILMI.S
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 1 : Introduction.
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
LIFI-Java 2004 Séance du Jeudi 9 sept. Cours 1. La notion de langage Décrire une tâche à effectuer –programme Écrire à un haut niveau –facile pour lutilisateur.
COURS DE PROGRAMMATION ORIENTEE OBJET :
COURS DE PROGRAMMATION ORIENTEE OBJET :
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
99 Réutilisation du code grâce à l'héritage. 9-2 Objectifs À la fin de ce cours, vous serez capables de : Définir l'héritage Utiliser l'héritage pour.
Héritage Licence Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier.
1212 Entrée et sortie de fichiers Objectifs À la fin de ce cours, vous serez capables de : • Lire à partir de la console • Écrire sur la console.
Programmer en langage c
JavaScript Nécessaire Web.
4 Introduction des objets. Les chaînes et tableaux
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
La notion de type revisitée en POO
Cours 61 6 La sécurité, Portée, Visibilité Programmer avec sécurité.
Introduction à la programmation objet avec java
11/04/ L'héritage Cours 7 Cours 7.
Programmation objet La base.
7ième Classe (Mardi, 24 novembre) CSI2572. Devoir 3 ?
Cours 7 Classes locales Clonage Divers: tableaux.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
© 2005 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java Peter Van Roy Département d’Ingénierie Informatique, UCL
Tutorat en bio-informatique
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
Les classes présenté par: RAHMOUNE RIME / ZEKRI SELMA.
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
C# de plus près.  Ce sont globalement les mêmes que Java : ◦ Int(int16, int32), float, double, bool,…  Les classe « communes » sont également les mêmes.
IUT du Limousin L.U.P Michel Vergnaud Programmation Objet - Java.
Héritage H. Batatia. plan Notion (que signifie l’héritage) Ecriture en java Héritage multiple (interdit) Instanciation (partie propre et partie héritée)
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
22 Concepts de base du langage Java. 2-2 Objectifs A la fin de ce cours, vous serez capables de : Identifier les éléments essentiels de Java Identifier.
pour les programmeurs en C++ Java 2 Part 1 3 Histoire de Java Projet de connexion des machines: 1991 Le nom Java a été introduit dans un café Développé.
Transcription de la présentation:

Approche fonctionnelle Approche objet JAVA Introduction Approche fonctionnelle Approche objet JAVA

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Bref Historique 1993 : projet Oak (langage pour l’électronique grand public) 1995 : Java / HotJava Mai 95 : Netscape prend la licence Sept 95 : JDK 1.0 b1 Déc 95 : Microsoft se dit intéressé Janv 96 : JDK 1.0.1 Fin 96 : RMI, JDBC, JavaBeans, … Fév 97 : JDK 1.1 1999 : JDK 1.2 (Java 2) 2000 : JDK 1.3 (Java 2) 2002 : JDK 1.4 (Java 2) HotJava est un navigateur Web écrit par SUN en Java, et capable d’exécuter des applets écrits précisément en byte code

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

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

Java est interprété JVM : Java Virtual Machine Essai.java Programme java Compilateur JAVA Programme en byte code Essai.java Essai.class Interpréteur 001101001 JVM : Java Virtual Machine La taille des types primitifs est indépendante de la plate-forme

Java est portable

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

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

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

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

Le JDK Java Development Kit Javac : compilateur de sources java Java : interpréteur de byte code Appletviewer : interpréteur d’applet Javadoc : générateur de documentation Java Virtual Machine API de Java Système d’exploitation Compilateur JDK ou plate-forme JAVA

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

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

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

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

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

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

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

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

La classe Clavier (1) méthode lireString // classe fournissant des fonctions de lecture au clavier import java.io.*; public class Clavier { public static String lireString () // lecture d’une chaine { String ligne_lue = null; try { InputStreamReader lecteur = new InputStreamReader (System.in); BufferedReader entree = new BufferedReader (lecteur); ligne_lue = entree.readLine(); } catch (IOException err) { System.exit(0);} return ligne_lue; Cette classe doit etre décrite dans un fichier de nom Clavier.java. Ce fichier doit être compilé. Le fichier utilisant cette classe doit aussi être compilé. L’exécution de ce dernier suffira. On peut mettre la classe clavier dans le même fichier. Dans ce cas, on doit retirer le mot clé public.

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

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

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

Exemple d’un petit programme // Calcul de racines carrees public class Racines { public static void main (String[] args) { final int NFOIS = 5; int i; double x; double racx; System.out.println (" Je vais vous calculer " + NFOIS + "racines carrées" ); for (i=0; i<NFOIS ; i++) { System.out.print (" Donnez un nombre : " ); x = Clavier.lireDouble (); if (x<0.0) System.out.println ( x + "  ne possede pas de racine carree "); else { racx = Math.sqrt(x); System.out.println (x + "  a pour racine carree : " + racx); } La syntaxe Java est fondée sur celle de C++. Il existe cependant quelques petites différences. Vous constatez dans ces exemple que le mot clé const a été remplacé par final.

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

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

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

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

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

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

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

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

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

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

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

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

Les classes et les objets Les attributs de classe (2) Ces propriétés sont partagées par tous les objets de cette classe Cercle - CoordonneeX : réel CoordonneeY : réel Rayon : réel - Nombre de cercles : entier - PI = 3.14 <<constructeur>> Cercle(réel r) { …} << modificateur >> plusGrand (Cercle c) : Cercle { …} plusGrand (Cercle c1, Cercle c2) : Cercle { … } Cette opération peut être utilisée directement au niveau de la classe sans passer par un objet.

Exemple en JAVA Déclaration des attributs de classe class Cercle { private static int nombreDeCercles = 0; private static double PI = 3.14; private double CoordonneeX, coordonneeY, rayon; public Cercle(double r) { rayon = r; nombreDecercles++;) public Cercle plusGrand(Cercle c) { if (c.rayon > rayon) return c; else return this; } public static Circle plusGrand(Cercle c1, Cercle c2) { if (c1.rayon > c2.rayon) return c1; else return c2; Cercle c1 = new Cercle(10); Cercle c2 = new Cercle(20); n = Cercle.nombreDeCercles; // n = 2; Cercle c3 = c1.plusGrand(c2); // c3 = c2; Cercle c4 = Cercle.plusGrand(c1, c2); // c4 = c2 Déclaration de méthode de classe Utilisation d’une méthode de classe à partir de la classe

Les classes et les objets Les attributs de classe (3) Les variables « static » sont communes à toutes les instances de la classe. Il n'est pas nécessaire d'instancier une classe pour accéder à un de ses membres statiques. Les méthodes statiques ne peuvent pas accéder à « this » le mot clé désignant l’objet dans tout sa globalité. Exemple utilisant le mot clé this : public Point (int x, int y) { this.x = x; this.y = x; }

Les classes et les objets Les tableaux : généralités Déclaration int [] tableau_entiers; // équivalent à : int tableau_entiers[]; Création et initialisation tableau_entiers = new int[42]; cube = new Color[256][256][256]; int [] primes = {1, 2, 3, 5, 7, 7+4}; tableau_entiers[0] = 3; Utilisation int l = tableau_entiers.length; // l = 42 int e = tableau_entiers[50]; // génère une exception ArrayIndexOutOfBoundsException

Les classes et les objets Les tableaux : Exemple 1 int t [] [] = { new int [3], new int [2] }; t[0][0] t[0][1] t[0] t[0][2] t[1] t[1][0] t t[1][1] t.length  2 ; t[0].length  2 ; t[1].length  3

Les classes et les objets Les tableaux : Exemple 2 int t [][]; t = new int [2] []; int [] t1 = new int [3]; int [] t2 = new int [2]; t[0] = t1; t[1] = t2; t1 t t2

Les classes et les objets Les tableaux d’objets public class TabPoint { public static void main (String args[]) {Point [] tp; tp=new Point [3]; tp[0] = new Point (1,2); tp[1] = new Point (4,5); tp[2] = new Point (8,9); for (int i = 0; i<tp.length; i++) tp[i].affiche(); }} class Point {private int x,y; public Point (int x, int y) {this.x; this.y=y;} public void affiche () { System.out.println (" Point : " + x + " , " + y);} }

Les classes et les objets Les arguments de la ligne de commande public class Echo { public static void main( String args [] ) { System.out.println("les arguments :"); for (int i=0 ; i < arg.length ; i++) System.out.println (arg[i]); } } Éxécution : $ java Echo “bonjour” 12 dd 2e les arguments : bonjour 12 dd 2e

Les classes et les objets Tableau en argument ou en retour public class TabArg { public static void main (String args []) { int t [] = {1,3,5,7}; System.out.print (" t avant : " ); Util.affiche(t); Util.raz(t); System.out.print (" \nt apres : " ); Util.affiche(t);}} class Util {static void raz (int t []) { for(int i=0; i < t.length; i++) t[i] = 0;} static void affiche (int t[]) { for (int i = 0; i<t.length; i++) System.out.print (t[i]+ " " );} }  t avant : 1 3 5 7 t apres : 0 0 0 0

Les classes et les objets La classe Vector (1) La classe Vector du package java.util permet de stocker des objets dans un tableau dont la taille évolue avec les besoins. 3 constructeurs : public Vector(int initialCapacity, int capacityIncrement) public Vector(int initialCapacity) public Vector() Variables membres : elementData qui contient les éléments du vecteur, elementCount qui précise le nombre d'élément valide dans ce tableau capacityIncrement qui fixe de combien le vecteur doit être étendu quand nécessaire. Si cette valeur vaut 0, le vecteur est doublé à chaque redimensionnement.

Les classes et les objets La classe Vector (2) Lire un objet O = vect.elementAt(n); Attention, la méthode elementAt renvoie par défaut des objets de type Object, un transtypage est souvent nécessaire. Par exemple, si l'élément d'indice 2 est de type Color, il faudra écrire : Color c = (Color) vect.elementAt(2);

Les classes et les objets La classe Vector (3) Quelques méthodes contains(Object) : indique si l'objet est contenu dans le Vector. copyInto(Object[]) : copie les éléments dans un tableau classique. firstElement() : renvoie le premier élément. indexOf(Object) : renvoie l'indice de l'objet insertElementAt(Object, int) : insère l'objet à l'indice indiqué isEmpty() : indique si le Vector est vide lastElement() : renvoie le dernier élément removeAllElements() : vide le Vector removeElementAt(int) : retire l'objet dont l'indice est donné setElementAt(Object, int) : place l'objet à l'indice donné size() : renvoie le nombre d'éléments

Les classes et les objets Remarques Le passage des paramètres se fait par valeur. La méthode « getClass » retourne un objet contenant la classe d ’exécution d ’un objet. Pour chaque type primitifs, il existe des classes enveloppes (wrapper). int i = 5; // Type primitif Integer j = new Integer (10); // Référence d ’objets Pour le type primitif Char, la classe enveloppe est Character.

Les classes et les objets L ’égalité Toutes les classes Java héritent implicitement de java.lang.Object, la classe objet de base de Java. Cette classe possède la méthode « equals » définie comme ceci : public boolean equals( Object obj) {return (this = = obj); } Utilisation de = = lorsqu ’on désire tester si deux types primitifs sont identiques ou si deux références objet pointent sur le même objet. Si nous désirons modifier le contenu de cette méthode, il suffit de la redéfinir. Dans les classes enveloppes la méthode « equals » a été redéfinie afin de tester l ’égalité de deux objets.

L’héritage Principes Une classe ne peut hériter (extends) que d’une seule classe Les classe dérivent, par défaut, de java.lang.Object. Une méthode d’une classe dérivée n’a pas accès aux membres privés de sa classe de base  utilisation de protected Une méthode d’une classe dérivée a accès aux membres publics de sa classe de base Le constructeur de la classe dérivée doit prendre en charge l’intégralité de la construction de l’objet Si un constructeur d’une classe dérivée appelle un constructeur d’une classe de base, il doit obligatoirement s’agir de la première instruction du constructeur et ce dernier est désigné par le mot clé super exemple : super (x,y); // appel d’un constructeur de la classe de base, auquel // on fournit en arguments les valeurs de x et de y. Une méthode déclarée final ne peut pas être redéfinie dans une classe dérivée. Une classe déclarée final ne peut plus être dérivée

L’héritage Exemple class Point { private int x,y; public Point (int x, int y) {this.x = x; this.y=y ;} public void deplace (int dx, int dy) { x += dx; y=+ dy;} public void affiche () {System.out.println (" Je suis en "  + x + "  "  +y); } } class Pointcol extends Point { private byte couleur; public Pointcol (int x, int y, byte couleur) { super (x,y); System.out.println (" et ma couleur est : "+ couleur);} public class TstPcol3 { public static void main (String args[]) { Pointcol pc1 = new Pointcol (3,8,(byte)2); pc1.affiche(); pc1.deplace(1,-3); pc1.affichec();}

L’héritage Le masquage des variables (1) Une classe peut définir des variables portant le même nom que celles de ses classes ancêtres Une classe peut accéder aux attributs redéfinis de sa classe mère en utilisant super ou par cast Une classe dérivée peut redéfinir une méthode de la classe de base Une classe peut accéder aux méthodes redéfinies de sa classe mère en utilisant super. Une classe dérivée peut sur-définir une méthode de la classe de base.

L’héritage Le masquage des variables (2) class A { protected int x; public void m() {...} } class B extends A{ class C extends B { protected int x, a; public void test() { a = super.x; // a reçoit la valeur de la variable x de la classe B a = super.super.x; // Syntax error a = ((B)this).x; // a reçoit la valeur de la variable x de la classe B a = ((A)this).x; // a reçoit la valeur de la variable x de la classe A super.m(); // Appel à la méthode m de la classe B super.super.m(); // Syntax error ((B)this).m(); // Appel à la méthode m de la classe C (et non B)