SlideShare une entreprise Scribd logo
Programmation Orientée Objet en Java El Mostafa DAOUDI  1,2 1  École Nationale des Sciences Appliquées [email_address] 2  Laboratoire  LaRI, Faculté des Sciences,  Département de Mathématiques et d’Informatique, FSO [email_address] Septembre 2007
Ch I. JAVA: les bases I. Généralités sur les objets Un objet est une variable améliorée: il stocke les données, mais on peut effectuer des requêtes sur cet objet (on demande à l’objet de faire des opérations sur lui-même), en envoyant un message à cet objet. Ceci est équivalent à un appel de fonction. Chaque objet à son espace mémoire: la simplicité des objet mis en œuvre, cache la complexité des programme. Chaque objet a un type précis: c’est-à-dire chaque objet est une instance (variable) d’une class (type) Un programme est ensemble d’objets qui s’envoient des messages.
II. Les bases à connaître Java est un langage orienté objet: l'entité de base de tout code Java est la classe Sa syntaxe est proche du langage C Il est fourni avec le JDK (Java Developpment Kit) Outils de développement Ensemble de paquetages très riches et très variés Multi-tâches ( threads ) Portable grâce à l’exécution par une machine  virtuelle
En Java,  tout se trouve dans une classe . Il ne peut y avoir de déclarations ou de code en dehors du corps d'une classe. La classe elle même ne contient pas directement du code.  Elle contient des déclarations de variables globales, que l'on appelle des ``attributs'',  et des  méthodes (équivalents à des fonctions).  Le code se trouve  exclusivement  dans le corps des méthodes, mais ces dernières peuvent aussi contenir des déclarations de variables locales (visibles uniquement dans le corps de la méthode).
III. Mon premier programme en Java Considérons le code source du programme qui affiche à l’écran Mon premier programme Java  // Fichier source MonPremProg.java public class  MonPremProg  {    // déclaration de données globales    //définition des  méthodes    public static void main(String args[]) {  // déclaration des  données locales;   System.out.println( "  Mon premier programme Java  "  );    }  }
De manière générale, dans tout programme autonome destiné à être exécuté doit contenir une méthode  particulière nommée  main()  définie de la manière suivante: public static void main(String args[]) {   /* corps de la méthode */ }   Le paramètre args de la méthode  main()  est un tableau d’objets de type  String . Il n’est pas utilisé mais, il est exigé par le compilateur Java. La classe contenant la méthode  main()  doit obligatoirement être  public  afin que la machine virtuelle y accès. Dans  l’exemple, le contenu de la classe  MonPremProg  est réduit à la définition d’une méthode  main() .
Un fichier source peut contenir plusieurs classes mais une seule doit être public(ici  PremProg ). Le nom du fichier source est identique au nom de la classe publique qu'il contient, suivi du suffixe .java, dans l’exemple  MonPremProg.java
Compilation   La compilation d’un programme Java ne traduit pas directement le code source en fichier exécutable. Elle traduit d’abord le code source en un code intermédiaire appelé «  bytecode  ». C’est le  bytecode  qui sera ensuite exécuté par une machine virtuelle (JVM ;  Java Virtual Machine ). Ceci permet de rendre le code indépendant de la machine qui va exécuter le programme.
Sun  fournit le compilateur  javac  avec le JDK.  Dans notre exemple on exécute:    javac   MonPremProg.java Cette compilation  crée un fichier nommé « MonPremProg .class » qui contient le  bytecode On peut désigner le fichier à compiler par un chemin absolu ou relatif :  javac home/user2/MonPremProg.java Si un système possède une JVM il peut exécuter tous les  bytecodes  (fichiers  .class ) compilés sur n’importe qu’ele autre système.
Exécution du  bytecode Le  bytecode  doit être exécuté par une JVM. Cette JVM n'existe pas ; elle est simulée par un programme qui lit les instructions (en  bytecode ) du programme  .class , les traduit dans le langage machine relatif à la machine sur laquelle il sera exécuté.  Lance leur exécution
Exécution avec  java Dans le cas de l’environnement JDK de SUN. Pour compiler il suffit d’utiliser la commande  javac : javac  MonPremProg.java Pour exécuter, Sun fournit le programme  java  qui simule une JVM. Il suffira d’utiliser la commande: java  MonPremProg qui interprète le  bytecode  de la méthode  main()   de la classe  MonPremProg
L’exécution du programme  MonPremProg  affiche à l’écran, comme résultat, la chaîne de caractères:  Mon premier programme Java,  grâce à l’instruction:  System.out.println( "  Mon premier programme Java  " ); Dans le programme, une ligne qui commence avec  //  est un commentaire jusqu’à la fin de la ligne Une ligne qui commence avec /*   est un commentaire qui peut être étalé sur      plusieurs lignes, et doit terminer avec  */
III. Les classes en Java Une classe décrit un ensemble d’objets qui partagent des caractéristiques communes. On définit une classe pour représenter un problème au lieu d’utiliser un type de données pour représenter une unité de stockage dans l’ordinateur. Créer des classes (des types de données abstraites) est un concept fondamental dans la POO.  On utilise les classes exactement de la même manière que les types de données prédéfinies.  On peut créer des variables (objets ou instance) d’un type particulier.
Pour créer un nouveau type d’objets de on utilise le mot clé  class . Le canevas de base pour définir un nouveau type de nom  NomDuType  est la suivante: class  NomDuType  { /* Corps de la classe: instructions de définitions    des méthodes et des champs */ }
Dans la définition de la classe (corps de la classe), on met deux types d’éléments: des données membres de la classe (appelées champs) qui sont des objets de n’importe quel type. des fonctions membres de la classe (appelées méthodes).
Exemple:   UnTest  est une classe (un nouveau type) qui a  3 champs :  float, int et boolean . class   UnTest  { float x; int i; boolean b; }
Définition des méthodes La définition de base d’une méthode ressemble à la définition d’une fonction en C.  typeRetour   nomMethode  (/* Liste des parametres */)  {  /* corps de la méthode */ } nomMethode   est le nom de la méthode Liste de paramètre (arguments de la méthode) donne les types et les noms des informations qu’on souhaite passer à la méthode lors de son appel. typeRetour  est le type de la valeur qui est retournée par la méthode après son appel. Si la méthode ne fourni aucun résultat, alors  typeRetour  est remplacé par le mot clé  void .
Le mode de passage des paramètres dans les méthodes dépend de la nature des paramètres : par  référence  pour les objets par  copie  pour les types primitifs   Exemple   class C  { void  methode1 (int i){  i+=12; } void  methode2 () { int i = 3; methode1(i); System.out.println( i="  + i);  // i=3 } }
IV. Création et manipulation d’Objets Une fois la classe est définie, on peut créer des objets de la même manière que la déclaration des types primitif:  Considérons la classe  ClasseTest class   ClasseTest  { // corps de la classe ClasseTest } l’instruction: ClasseTest   a;   // déclare a comme objet (variable)  de type  ClasseTest
Attention:   La déclaration d’une variable de type primitif réserve un emplacement mémoire pour stocker la variable La déclaration d’un objet de type A, ne réserve pas une place mémoire pour un objet de type A, mais seulement un emplacement pour une référence à un objet de type A.    les objets sont manipulés avec des références.  Exemple classique de la télécommande et la Télé. Télé = objet Télécommande = référence. Télécommande Télé Référence Objet
Pour modifier l’objet (par exemple augmenter le son, …) on utilise la référence (la télécommande). Avoir une référence ne veut pas dire avoir l’objet (on peut avoir la télécommande sans avoir la télé).
L’emplacement pour l’objet doit être demandé explicitement dans le programme en faisant appel à l’opérateur  new .   L’expression  new   NomClasse  créée un emplacement pour un objet de type  NomClasse.   class  NomClasse { /* Corps de la classe */ } NomClasse  a =  new   NomClasse(); En générale: Chaque objet met ses données membres dans sa propre zone mémoire. Les données membres ne sont partagées entre les objets.
Exemple 1: class   UnTest  {   float  x;   int  i;   boolean  b; } UnTest  data =  new   UnTest ();  // créer un objet data
Exemple 2: Supposons qu’on veut avoir une chaîne de caractères alors on crée une référence sur String: String  s; Ici on a créé la référence mais pas l’objet. Pour créer l’objet, il faut initialiser la référence s. String  s= new String  ("cours Java"); ou String  s; s =  new String  ("cours Java"); Ou tout simplement ( C’est un cas particulier en Java pour les objets string) par: String  s= " cours Java "
Accès aux données membres   Exemple 1: class   UnTest  {   float  x;   int  i;   boolean  b; } UnTest  data =  new   UnTest ();  // créer un objet data Maintenant l’objet dont la référence  data  existe. Pour accéder à une donnée membre on indique le nom de la référence à l’objet suivi par un point, suivi par le nom du membre dans l’objet de la manière suivante: data.i=2;   // affecte 2 au membre i data.b=true;   // affecte true au membre b data.x=1.2f;   // affecte 1.2 au membre x.
Appels des méthodes Les méthodes ne peuvent être créer que comme des composante d’une classe. Une méthode ne peut être appelée que pour un objet. L’appel d’une méthode pour un objet se réalise en nommant l’objet suivi d’un point suivi du nom de la méthode et de sa liste d’arguments: nomObjet.nomMethode(arg1, ….).   où nomObjet : nom de la référence à l’objet nomMethode : nom de la méthode.
Exemple:  soit f () une méthode qui ne prend aucun paramètre et qui retourne une valeur de type int.  Alors si on a une référence à un objet appelé a pour lequel f() peut être appelée, on peut écrire:  int x = a.f() class   UnTest  {   float  x;   int  i;   boolean  b; int f() { return 10; } } UnTest   a =  new   UnTest ();  // créer un objet a; int  x = a.f();  // affecte à x la valeur retournée par f
Cas particulier des types primitifs Les types primitifs ont un traitement particulier:  on n’utilise pas  new ,  les variables (non les références) sont créées au moment de leurs déclaration. ------------------------------------------------------------------------------ Type   | Taille | Classe Wrapper   | ---------  |--------------------------------|--------------------------------- | Boolean |   | Boolean | char   | 16 bits, Unicode | Character   | byte   | 8 bits | Byte  | short   | 16 bits | Short    | int    | 32 bits | Integer  | long   | 64 bits | Long  | float   | 32 bits IEEE 754 | Float  | double   | 64 bits IEEE 754 | Double | void   | | Void  |
On peut traiter les type primitif comme des objet en utilisant les classe wrapper qui leurs sont associées. Exemple: char  c=‘x’;  // type primitif directement déclaré Character   car =  new   Character (c); // classe wrapper ou Character  car =  new Character  (‘x’);
Remarque : Quand une donnée d’un type primitif est membre d’une classe on est assuré qu’elle a une valeur par défaut même si on ne l’initialise pas: ---------------------------------------------------------------- Type primitifs | Valeur par défaut | ---------------------------- | ----------------------------------- | boolean  | false | char | ‘0000’ (null) | byte |  (byte)0 | short | (short)0 | int |  0 | long  |  0L | float  |  0.0f | double | 0.0d | -----------------------------------------------------------------
Attention:  Cette garanti d’initialisation par défaut ne s’applique pas aux variables locales (définition d’une fonction (méthode)).
V. Notion de portée et de durée de vie des objets Le concept de portée fixe simultanément la visibilité et la durée de vie des noms définis dans cette portée. La portée est fixée par les accolades  { } . Exemple: { int  x=12;  //  seul x est accessible { int  q=96;  //  x et q tous les deux sont accessibles } //  seul x est accessible //  q est hors de portée }
Attention:  Ceci n’est pas permis en Java { int  x=12;  { int  x=96;  //  illégale en Java, valable en C, C++ } }
Portée des objet:  Considérons une classe nommée A { A a= new  A();  } // fin de portée La référence  a  disparaît à la fin de la portée, par contre l’objet qui été référencé par  a  existe toujours, mais on n’a aucun contrôle sur lui (il reste inaccessible).  Les objets n’ont pas la même durée de vie que les types primitifs.
Il n’existe aucun opérateur explicite pour détruire l’objet dont on n’a pas besoin, mais il existe un mécanisme de gestion automatique de la mémoire connu sous le nom de ramasse miettes (en anglais Garbage Collector). Son principe est le suivant: A tout instant on connaît le nombre de références à un objet donné. Lorsqu’il n’existe plus aucune référence sur un objet, on est certains que le programme ne peut pas y accéder, donc l’objet devient candidat au ramasse miette.
VI.  Champs de classe Considérons la définition simpliste suivante: class   A  { int  n; float  y; }  Chaque objet de type A possède ses propres champs n et x. Par exemple avec les déclarations  A  a1= new   A (), a2=  new   A (); a1.n et a2.n  désignent deux champs différents.  a1.y et a2.y  désignent aussi deux champs différents.
On peut définir des champs qui n’existent qu’en un seul exemplaire (ce qu’on nomme des champs de classe ou champs statiques), en les déclarant avec l’attribut  static . Par exemple si nous définissons: class A { static int  n; float  y; } A  a1= new   A (), a2= new   A (); a1.n et a2.n  désignent donc le même champs. Il est possible de    s’y référer en le nommant simplement  A .n  // champs (statique) de la classe  A
VII. Quelques précisions Identificateur:   C’est une suite de caractères pour désigner les différentes entités manipulés par un programme: variables, méthode, classe, objet, …  Il est formé de lettre et/ou de chiffres. Le premier caractère est une lettre ou le caractère souligné (_). Remarque:   Tous les caractères sont significatifs.  On fait la différence entre les majuscules et les minuscules. Mots clés:  certains mots sont réservés par le langage et ne peuvent pas être utilisés comme identificateur.
Mise en page des programmes La mise en page d’un programme Java est libre.  Une instruction peut être étendue sur plusieurs lignes. Une ligne peut comporter plusieurs instructions Emploi du code Unicode: Java utilise le codage Unicode, qui est basé sur 2 octets (16 bits), par conséquent on peut coder 65 536 symboles, ce qui permet de couvrir la plus part des symboles utilisés dans le monde. Pour assurer la portabilité, le compilateur commence par traduire le fichier source en Unicode. On peut, par exemple, utiliser l’identificateur élément:  int  élément;  On peut aussi utiliser le code Unicode d’un caractère (mais à éviter pour la lisibilité) de la manière suivante: xxxx représente le caractère ayant comme code Unicode la valeur xxxx. Par exemple 0041 représente le caractère A.
Style de programmation non standard Mettre en Majuscule la première lettre des noms des classes. Exemple:   class A () {  //… } Si le nom de la classe est composée de plusieurs mots, ils sont accolés (on ne les sépare pas par un trait bas) et la première lettre de chaque mot est mise en majuscule.  Exemple: class PremProg() { //…. }  - Pour le reste, méthodes, variables membres, noms des références d’objets, le style retenu comme classe sauf que la première lettre de l’identificateur est miniscule.
Spécificateurs d’accès:   Il existe 3 mots clés pour spécifier l’accès au sein d’une classe:  public ,  private  et  protected . public : veut dire tout le monde private  : veut dire que personne ne peut accéder à ces définitions à part les méthodes interne de ce type. protected : se comporte comme  private  avec moins de restriction. Une classe dérivée a un accès aux membres  protected  mais pas aux membres  private   Accès par défaut, lorsqu’aucun de ces spécificateurs n’est mentionné.
Exemple:   class   A  { public   int  x; private   int  y; public   void  initialise (int i, int j){ x=i; y=j; } }  public class  TestA{  // fichier source de nom TestA.java public static void main  (String args[]) {  A a; a= new  A();  //  On peut aussi déclarer A a= new  A(); a.initialise(1,3);  //  x vaut 1 et y vaut 3 a.x=2; //  x vaut maintenant 2. On peut accéder à x car il est public a.y=3; //  ne compile pas car y est privée } }
Ch. II. Les constructeurs I . Introduction Un objet a –  une adresse en mémoire (identifie l’objet) –  un comportement (ou interface) –  un état interne (les valeurs des variables) L’état interne est donné par des valeurs de variables Le comportement est donné par des fonctions ou procédures, appelées méthodes
Nous supposons qu’un objet de type Point est représenté par: Un état interne : deux coordonnées entières l’abscisse (x) et l’ordonnée (y). Un Comportement: nous supposons que la classe dispose des trois méthodes: initialise  pour attribuer des valeurs aux coordonnées d’un points déplace  pour modifier les coordonnées d’un point  affiche  pour afficher les coordonnées d’un point
public   class  Point{ private   int  x;  // abscisse private   int  y; // ordonnée public  void initialise (int abs,int ord){ x=abs; y=ord; }   public   void  deplace (int dx, int dy){ x+=dx; y+=dy; }   public   void  affiche (){ System.out.println( "  abscisse  : "+ x + "  ordonnée  : " + y ); } }
Pour manipuler un objet, on déclare une référence sur la classe de cet objet : Exemple:   Point a; Pour créer un objet ( instance de la classe ), on applique l'opérateur new.  Exemple:   a =  new  Point(); Quand une instance est créée,  - son état est conservé dans les variables d’instance (son propre état interne) - partage le code qui détermine son comportement (les méthodes) avec les autres instances de la classe.
Ainsi  a= new  Point();  // créer un objet de type Point et place sa référence dans a. Les objets interagissent en s’envoyant des messages: Les méthodes d’un objet correspondent aux messages qu’on peut lui envoyer : quand un objet reçoit un message, il exécute la méthode correspondante. De manière générale on a:  objetQuiReçoitLeMessage.messageEnvoyé(paramètres); Exemple des objets de type  point: a.initialise(1,1); a.deplace(0,2);
public class  TstPoint{  public static void main  (String args[]) {  Point a; a= new  Point(); a.initialise(1,1); a.deplace(2,0); Point b= new  Point(); b.initialise(2,3); b.affiche(); } }
Remarque: Pour chaque instance on appelle la méthode initialise pour initialiser l’objet ainsi créer. Si on n’appelle pas la méthode initialise, l’objet de type Point ainsi créer ne sera pas initialisé.    Créer un objet, ne garanti pas son initialisation
II. Définitions de Constructeur On peut garantir l’initialisation d’un objet grâce à une méthode spéciale appelée constructeur qui permet d’automatiser le mécanisme d’initialisation d’un objet.  Quand une classe possède un constructeur, Java l’appel automatiquement à toute création d’objet avant qu’il ne puisse être utilisé. La création et l’initialisation sont deux concepts unifiés
Chaque classe a un ou plusieurs constructeurs qui servent à créer les instances initialiser l’état de ces instances Un constructeur est une méthode qui: porte le même nom que la classe n’a pas de type retour peut disposer d’un nombre quelconque d’arguments (éventuellement aucun). Exemple: Prenons l’exemple de la classe point et transformons la méthode initialise en un constructeur en la nommant Point.
public   class  Point{ private   int  x;  // abscisse private   int  y; // ordonnée public  Point (int abs, int ord) {  //  Constructeur, remplace initialise x=abs; y=ord; }   public   void  deplace (int dx, int dy){ x+=dx; y+=dy; }   public   void  affiche (){ System.out.println( "  abscisse  : "+ x + "  ordonnée  : " + y ); } }
Les instructions: Point a= new  Point(); a.initialise(1,1)  Sont remplacées par  Point a =  new  Point(1,1);  // crée l’instance et l’initialise  On peut aussi écrire: Point a; a= new  Point(1,1);   Attention.   Dans la dernière version de la définition de la classe Point, l’instruction  Point a =  new  Point();  ne convient plus car le constructeur a besoin de deux arguments
Un autre exemple public class  Etudiant { private  String nom, prenom;  // Variables d’instance private  int codeNatEtudiant; // Constructeur public  Etudiant(String n, String p) {   nom = n;   prenom = p; } public  void setCNE (int cne) {   codeNatEtudiant = cne; } public static void main(String[] args)  {   Etudiant e1;   e1 = new Etudiant("Mohammed", "Ali"); // création d'une instance de la classe  Etudiant   e1.setCNE(23456765); } }
III. Quelques règles concernant les constructeurs 1. Aucun type, même void, ne doit figurer devant son nom. 2.  Lorsque le code d’une classe ne comporte pas de constructeur, un constructeur par défaut sera automatiquement ajouté par Java.  Dans ce cas  on peut créer des instances (objets) de la classe  par des instructions telles que: Point a= new  Point(); // ok si Point n’a pas de constructeur Etudiant e= new  Etudiant(); // ok si Etudiant n’a pas de constructeur
De manière générale: Si pour une classe A donnée, l’instruction suivante est acceptée  A a= new  A(); Cela signifie que: Soit A ne possède pas de constructeur Soit A possède un constructeur sans arguments.
3. Un constructeur ne peut pas être appelé de la même manière que les autres méthodes. Par exemple: Point a= new  Point(1,1); // ok car Point possède un constructeur e1.Etudiant(("Mohammed", "Ali");  //  Interdit car Etudiant possède  // un constructeur. 4. Un constructeur peut être déclaré  private . Dans ce cas il ne pourra plus être appelé de l’extérieur, c’est-à-dire il ne pourra pas être utiliser pour instancier des objet. Exemple: class  A{ private  A() { … } // constructeur privée sans arguments … }  … A a=new A(); // erreur,  le constructeur correspondant A() est privé
Dans les exemples précédents, le constructeur initialise les champs privés de l’objet.  Remarque:  les champs d’un objet sont toujours initialisés par défaut, contrairement à ce qui se passe pour les variables locales, .  La création d’un objet entraîne toujours, par ordre chronologique, les opérations suivantes: Initialisation par défaut de tous les champs de l’objet Une initialisation explicite lors de la déclaration du champ L’exécution des instructions du corps du constructeur
Initialisation par défaut des champs d’un objet :   ------------------------------------ |--------------------------------- Type du champ | Valeur par défaut ------------------------------------ |-------------------------------- boolean   | false char   | caractère de code nul int, byte, short, int long | 0 float ,  double |  0.f ou 0. class | null ---------------------------------------------------------------------
Initialisation explicite des champs d’un objet :   Une variable locale peut être initialiser lors de sa déclaration. Il en va de même pour un champs. Considérons: class  A{ public  A (…) {… }  // Constructeur A … private  int n=10; private  int p; }
L’instruction suivante  A  objA = new  A(…); Entraîne successivement l’initialisation implicite des champs n et p de l’objet  objA  à 0 L’initialisation (explicite) du champ n à la valeur figurant dans sa déclaration, soit 10 L’exécution des instruction du constructeur
Appel du constructeur Le corps du constructeur n’est exécuté qu’après l’initialisation par défaut et l’initialisation explicite.
class  A { public  A() {  // ici n vaut 20, p vaut 10 et np vaut 0 np=n*p;  n=5; } public void  affiche(){ System.out.println ( " n= " +n+" p= " +p+ "  np=  "  + np) } private  int n=20, p=10; private  int np; }  public class  Init {   public static void main  (String args[]) { A a= new A() ;  // ici  a.n vaut 5, a.p vaut 10, mais a.np vaut 200 a.affiche(); } } Résultat de l’appel de la méthode affiche:  n=5  p=10  np = 200
IV. Surcharge des méthodes On parle de surcharge (en anglais overload) lorsqu’un même symbole possède plusieurs significations différentes entre lesquelles on choisit en fonction du contexte. Par exemple a+b, la signification du symbole + dépend du type des variables a et b. En Java et C++, on peut surcharger  une méthode , c’est-à-dire, ajouter une méthode qui a le même nom mais pas la même signature qu’une autre méthode :
Considérons l’exemple suivant ou la classe  Etudiant  est dotée de 2 méthodes calcMoyenne: La première a deux arguments de ype float La deuxième a quatre arguments de type float
class  Etudiant { private  String nom, prenom;  // Variables d’instance private  int codeNatEtudiant; // Constructeur public  Etudiant(String n, String p) {   nom = n;   prenom = p; } public  void setCNE (int cne) {   codeNatEtudiant = cne; } public  float calcMoyenne(float m1, float m2) {  return (m1+m2)/2; } public  float calcMoyenne(float m1, float m2, float m3, float m4) {  return (m1+m2+m3+m4)/4; } }
public class TestEtudiant { public static void main(String[] args) {   Etudiant e1;   e1 = new Etudiant("Mohammed", "Ali"); //   e1.setCNE(23456765);   System.out.println ( “Moy1 = " +e1.calcMoyenne(10, 12));   System.out.println ( “Moy2 = " +e1.calcMoyenne(10, 12, 8, 13)); } }
Considérons maintenant l’exemple suivant ou la classe Point est dotée de 3 méthodes déplace: La première a deux arguments de type int La deuxième a un seul argument de type int La troisième a un seul argument de type short
class  Point { public  Point (int abs, int ord){ // Constructeur x=abs; y=ord; } pubic void  deplace (int dx, int dy) { x+=dx; y+=dy; } pubic void  deplace (int dx) { x+=dx; } pubic void  deplace (short dx) { x+=dx; } private int x,y; }
public class  Surdef1 { public static void main (String arg[]) { Point a=new Point(1,2); a.deplace(1,3);  // appel deplace (int,int) a.deplace(2); // appel deplace (int) short p=3; a.deplace(p); // appel deplace (short) byte b=2; a.deplace(b);    /*  appel deplace(short) après    conversion de b en short */ } }
Il peut y avoir ambiguïté Supposons que la classe Point est dotée des deux méthodes deplace suivantes: public void  deplace(int dx, byte dy) {  x+=dx; y+=dy; } public void  deplace(byte dx, int dy) {  x+=dx; } Considérons alors les instructions suivantes: Point a = new  Point(2,4) int  n; byte b; a.deplace(n,b);  // ok appel de deplace (int,byte) a.deplace(b,n); // ok appel de deplace (byte,n) a.deplace(b,b); // erreur, ambiguité
En Java, il est interdit de surcharger une méthode en changeant le type de retour uniquement: c’est-à-dire ne différencier les 2 méthodes que par leur type retour Par exemple, one peut pas avoir les 2 méthodes  suivante dans une classe : int moyenne(int, int);  // division entière par 2 float moyenne(int,int); // moyenne réelle
Surcharge des constructeurs (Plusieurs constructeurs) En Java et C++, une classe peut avoir plusieurs constructeurs. Comme le nom du constructeur est identique du nom de la classe, il ne peut y avoir qu’un seul nom de constructeur. Par contre on peut avoir différentes initialisations. class  Etudiant { private  String nom, prenom;  // Variables d’instance private  int codeNatEtudiant; public  Etudiant(String n, String p) {  // Constructeur   nom = n;   prenom = p; } public  Etudiant(String n, String p, int cne) {// Constructeur   nom = n;   prenom = p;   codeNatEtudiant = cne; } }
public class TestEtudiant { public static void main(String[] args) {   Etudiant e1, e2;   e1 = new Etudiant("Mohammed", "Ali");    e2 = new Etudiant("Ouardi", " fatima", 22564321);  } }
V. Autoréférences: emploi de this Il se peut qu’au seine d’une méthode, on ait besoin de faire référence à l’objet ayant appelé cette méthode. class  A {  … . public void  f(….) { ……  // ici l’emploi de  this  désigne la référence à l’objet  // ayant appelé la méthode f } }
Exemple 1: class  Point { public  Point (int abs, int ord){  x=abs; y=ord; } … private  int x, y; } Comme les identificateurs abs et ord sont des arguments muets pour la méthode Point, alors on peut les noter x et y qui n’ont rien avoir avec les champs  private  x et y. Dans ce cas la classe Point peut s’écrire comme suit:
class  Point { public  Point (int x, int y){  this .x=x;  // this .x permet d’accéder au champs x de l’objet courant   this .y=y;  // this .y permet d’accéder au champs y de l’objet courant   } … private  int x,y; }
Exemple 2: class  Etudiant { private  String nom, prenom;  public  Etudiant(String nom, String prenom) {    this.nom = nom; this.prenom = prenom; } }
Exemple 3:   Deux objets de même classe Point coïncident si leurs coordonnées sont identiques. On peut écrire la méthode coïncide de la façon suivante: pubic boolean  coincide (Point pt) { return ((pt.x== this .x) && (pt.y== this .y))  } Point a= new  Point(x1,y1); Point b= new  Point(x2,y2); Les point a est b sont identiques si: a.coincide(b) est TRUE
Utilisation du mot clé this dans un constructeurs Il est possible, qu’au sein d’un constructeur, on peut appeler un autre constructeur de la même classe. Pour faire on fait appel au mot clé  this  qui est utilisé cette fois comme nom de méthode.  Supposons que la classe Point admet deux constructeurs. Un constructeur initialise à l’origine (au point (0,0)) et un autre initialise à un point quelconque.
Version 1:   La classe Point peut être définie de la façon suivante: class  Point { public  Point ( int  abs,  int  ord){  x=abs; y=ord; } public  Point( ) { x=0; y=0; } … private   int  x,y; } Point a =  new  Point ();  // créer l’objet a et l’initialise à l’origine,   // au point (0,0). Point b =  new  Point (2,3);  // créer l’objet b et l’initialise au poi nt (2,3).
Version 2:  la classe Point peut être définie de la façon suivante: class  Point { public  Point ( int  abs,  int  ord){  x=abs; y=ord; } public  Point( ) { this  (0,0); } … private  int x,y; } Point a =  new  Point ();  // créer l’objet a et l’initialise à l’origine, // au point (0,0). Point b =  new  Point (2,3);  // créer l’objet b et l’initialise au point (2,3).
public class  feuille { int i=0; feuille increment () { i++; return this; } public  static void main (String[] args ) { feuille x=new feuille (); System.out.println("ii  =  " + x.increment().increment().increment().i ); } } Sortie:  i= 3
public class  feuille { int i=0; feuille increment () { i++; return this; } void print () { System.out.println (" i  =  " + i);  } public  static void main (String[] args ) { feuille x=new feuille (); x.increment().increment().increment().print( ) } } Sortie:  i= 3
Ch. III.  Généralités sur les structures lexicales de Java Types de variables Les variables d’instances sont déclarées en dehors de toute méthode conservent l’état d’un objet, instance de la classe sont accessibles et partagées par toutes les méthodes de la classe Les variables locales sont déclarées à l’intérieur d’une méthode conservent une valeur utilisée pendant l’exécution de la méthode ne sont accessibles que dans le bloc dans lequel elles ont été déclarées
Identificateurs Un identificateur Java  est une chaîne de caractères de longueur quelconque: Le premier caractère est une lettre Unicode Le reste de la chaîne peut contenir des lettres et/ou des chiffres et/ou le caractère souligné « _ » Les minuscules et les majuscules sont différenciés Un identificateur Java ne doit pas être un mot-clé ou les constantes  true ,  false  ou  null
L’affectation L’affectation est réalisée au moyen de l’opérateur « = ». Signifie prendre la valeur du coté droit et la copier du coté gauche.  La partie droite est une constante, une variable ou une expression qui retourne une valeur. La partie gauche est une variable . variable = constante ou variable ou expression
Soient A et B de type primitif  A=B;  signifie que le contenu de B est copié dans A.  Si ensuite on modifie le contenu de A, alors le contenu de B ne sera pas modifié. Soient A est B deux objets,  A=B;  signifie qu’on copie la référence de B dans A. (A et B pointeront vers le même objet référencé par B).  Si ensuite le contenu de A  ou  de B sont modifiés alors le contenu de A  et  de B sont modifiés.
Exemple:   class A { public int i; } public class TestAffectation { public static void main(String[] args) { A a=new A();  A b=new A(); a.i=6;  b.i=11; a=b;  // a et b contiennent la même référence, on a:  a.i=11 a.i=20;  // b.i  et  a.i  valent 20 b.i=13;  // a.i  et  b.i  valent 13. } }
Types de données en Java 2 grands groupes de types de données sont manipulés par Java: types primitifs objets (instances de classe)
Types primitifs Boolean:  prend deux valeurs  true  ou  false Nombres entiers :   byte:  représenté sur   1 octet,  short:  représenté sur   2 octets,  int :  représenté sur   4 octets,  long :  représenté sur   8 octets Nombres à virgule flottante :   float  : représenté sur 4 octets),  double :  représenté sur   8 octets Caractère (un seul caractère) :   char :  codé sur 2 octet par le codage Unicode
Nombres entiers byte  :  compris entre –128 et 127 short  :  compris entre –32 768 et 32 767 int  : compris entre –2.147 483 648 et 2 147 483 647 long  : compris entre  -923 372 036 854 775 808 et   923 372 036 854 775 807
Constantes nombres Une constante « entière »  est de type  int Si elle est suffixée par « L » alors elle est de type  long Exemple: 108  // constante de type int 89L  // constante de type long 014  // 14 en octal (base 8)= 12 en décimal 0xA7  // A7 en hexadécimal (base 16) = 167 en décimal
Types des résultats des calculs avec des nombres entiers Tout calcul entre entiers donne un résultat de type  int si au moins un des opérandes est de type  long , alors le   r ésultat est de type  long  Exemple byte b1 = (byte)20; byte b2 = (byte)15; byte b3 = b1 + b2; provoquera une erreur  car b1 + b2 est de type int (codé sur 32 bits) alors que b3 est de type byte (codé sur 8 bits seulement)
Les nombres flottants float  : environ 7 chiffres significatifs ;  valeur absolue (arrondie) maximal  3,4 x 10 38  ( constante prédéfinie  Float.MAX_VALUE ) valeur absolue (arrondie) minimal 1,4 x 10 -45  (constante prédéfinie  Float.MIN_VALUE ) double  : environ 15 chiffres significatifs ;  valeur absolue maximal (arrondie) 1,8 x 10 308  (constante prédéfinie  Double.MAX_VALUE ) valeur absolue minimal (arrondie) 4,9 x 10 -324  (constante prédéfinie  Double.MIN_VALUE )
Constantes nombres Une constante réelle est de type  float  si elle est suffixée par « F » et de type  double  sinon Exemple: .567e2  // 5,67 de type double 5.123E-2F  // 0,05123  type float
Type caractère permet de manipuler des caractères: Java représente un caractère sur 2 octets  Une variable de type caractère est déclaré par:  char  c1,c2; Constante de type caractère:  ‘a’  ,  ‘E’ Les caractères disposant d’une notation spéciale. Notation Code Unicode Abréviation usuelle Signification       amp;quot;   0008 0009 000a 000c 000d 0022 0027 005c BS(Back Space) HT(Horizontal Tabulation) LF(Line Feed) FF(Form Feed) CR(Cariage Return)  Retour arrière Tabulation horizontale Saut de ligne Saut de page Retour chariot
Type booléen Sert à représenter une valeur logique du type vrai/faux Une variable de type booléen est déclaré par:  boolean  b; b prend une des deux valeurs  false   ou  true
Constante null  Référence inexistante (indique qu’une variable de type non primitif ne référence rien) ; convient pour  tous les types non primitifs null
Transtypage Java est un langage fortement typé Dans certains cas, il est nécessaire de forcer le programme à considérer une expression comme étant d’un type qui n’est pas son type réel ou déclaré On utilise pour cela le  cast   (transtypage) :  ( type-forcé )  expression int  x = 10, y = 3;  double  z;   z=x/y;  // donne z=3.0;  car x/y donne 3 // sin on veut que z=3.3333.. et pas 3.0 z = (double)x / y;  // cast de x suffit
Casts  autorisés En Java, 2 seuls cas sont autorisés pour les  casts  : entre types primitifs, entre classes mère/ancêtre et classes filles.
Casts  entre types primitifs Un  cast  entre types primitifs peut occasionner une perte de données : conversion d'un  int  vers un  short Un  cast  peut provoquer une simple perte de précision: la conversion d'un  long  vers un  float  peut faire perdre des chiffres significatifs mais pas l'ordre de grandeur
Casts  entre types primitifs Une affectation entre types primitifs peut utiliser un  cast  implicite si elle ne provoque aucune perte De même, on peut affecter un entier à une variable de type nombre à virgule flottante Sinon, elle doivent comporter un  cast  explicite L’oubli de ce  cast  explicite provoque une erreur à la compilation
Exemples de Casts short s = 1000000; // erreur ! Cas particulier d’une affectation statique (repérable par le compilateur) d’un  int  « petit » :  short s = 65; // pas d’erreur Pour une affectation non statique, le  cast  est obligatoire : int i = 60; short b = (short)(i + 5); Les  casts  de types « flottants » vers les types entiers tronquent les nombres : int i = (int)1.99;  // i = 1, et pas 2
Casts  entre entiers et caractères Ils font correspondre un entier et un caractère qui a comme code Unicode la valeur de l’entier La correspondance  char  ->  int ,  long  s’obtient par  cast  implicite Le code d’un  char  peut aller de 0 à 65.535 donc  char  ->  short ,  byte  nécessite un  cast  explicite ( short  ne va que jusqu’à 32.767) Les entiers sont signés et pas les  char  donc  long ,  int ,  short  ou  byte  ->  char  nécessite un  cast  explicite
L’attribut final L’attribut  final   indique que la valeur de la variable ne peut être modifiée : on pourra lui donner une valeur une seule fois dans le programme. Variable d’instance final Une variable  d’instance  final   est constante pour chaque objet.  Attention:   elle peut avoir 2 valeurs différentes pour 2 objets différents. Une variable d'instance  final   peut ne pas être initialisée à sa déclaration mais elle doit avoir une valeur à la sortie de tous les constructeurs
Variable locale final Si la variable est d’un type primitif, sa valeur ne peut changer Si la variable référence un objet, elle ne pourra référencer un autre objet mais l’état de l’objet pourra être modifié final Etudiant e = new Etudiant("Mohammed", "Ali"); . . . e.nom = "Ahmed";  // ok, changement de l’état e l’objet e.setCNE(32211452);    // ok, changement de l’état e l’objet e = new Etudiant("Ahmed");  //  Interdit , référence à un  // autre objet
Instructions de contrôle
Structure Alternative « if… else » if ( expressionBooléenne ) bloc-instructions ou instruction else bloc-instructions ou instruction int x = y + 5; if (x % 2 == 0) { type = 0; x++; } else type = 1; Un bloc serait préférable, même s’il n’y a qu’une seule instruction
Expression conditionnelle expressionBooléenne  ?  expression1  :  expression2 Est équivalent if ( expressionBooléenne)  expression1; else   expression2; Exemple: int y = (x % 2 == 0) ? x + 1 : x; est équivalent à int y; if (x % 2 == 0) y = x + 1; else y = x; Parenthèses pas indispensables
Distinction de cas suivant une valeur switch( expression ) { case  val1 :  instructions ; break;  //  Attention, sans  break , les instructions du cas suivant  // sont exécutées ! ... case  valn :  instructions ; break; default:  instructions ; } expression  est de type  char ,  byte ,  short , ou  int , ou de type énumération S’il n’y a pas de clause  default ,  rien n’est exécuté si  expression  ne correspond à aucun  case
Exemple de switch char lettre; int nbVoyelles = 0, nbA = 0, nbT = 0, nbAutre = 0; . . . switch (lettre) { case 'a' : nbA++; case 'e' :  // pas d’instruction ! case 'i' : nbVoyelles++; break; case 't' : nbT++; break; default : nbAutre++; }
Répétitions « tant que » while( expressionBooléenne ) bloc-instructions ou instruction do  bloc-instructions ou instruction while( expressionBooléenne ) Le bloc d’instructions est exécuté au moins une fois
Répétition for for( init ;  test ;  incrément ){ instructions ; } est équivalent à init ; while ( test ) { instructions ; incrément }
Exemple de  for int somme = 0; for (int i=0; i < n; i++) { somme += tab[i]; } System.out.println(somme);
Instructions liées aux boucles break  sort de la boucle et continue après la boucle continue  passe à l’itération suivante break  et  continue  peuvent être suivis d’un nom d’étiquette qui désigne une boucle englobant la boucle où elles se trouvent (une étiquette ne peut se trouver que devant une boucle)
Etiquette de boucles boucleWhile: while (pasFini) { ... for (int i=0; i < n; i++) { ... if (t[i] < 0) continue boucleWhile; ... } ... }
Les tableaux En Java les tableaux sont considérés comme des objets. –  les variables de type tableau contiennent des références aux tableaux –  les tableaux sont créés par l’opérateur  new –  ils ont une variable d’instance ( final ) pour désigner taille du tableau: final int length
Déclaration et création des tableaux Déclaration :  La taille n’est pas fixée à la déclaration int[] tabNotes; Ou int tabNotes[];  //  possible, mais non recommandé  Attention:   En java il n'est pas possible de définir des tableaux de taille statique à la déclaration.  int[10]   tab; // ne compile pas  Création :  C’est pendant la création qu’il faut donner la taille du tableau tabNotes = new int[5]; Remarques:   Chaque élément du tableau reçoit la valeur par défaut du type de base du tableau La taille ne pourra plus être modifiée par la suite Les éléments d’un tableau peuvent être d’un type primitif ou d’un type objet
Initialisation On peut lier la déclaration, la création et l’initialisation d’un tableau;  Sa longueur est alors calculée automatiquement d’après le nombre de valeurs données. Attention  : cette syntaxe n'est autorisée que dans la déclaration) : int[] tab = {10, 3*6, 4}; Etudiant [] etudiantsSMI = { new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;), new Etudiant( &quot; Fatima&quot;,  &quot; Zahra&quot;) } On peut affecter « en bloc » tous les éléments d'un tableau avec un tableau anonyme  int[] t; t = new int[] {1, 2, 3};
Indices du  tableau:  Les indices du tableau commence à  0  et se termine à  tab.length - 1 Taille du tableau int[] tab = {10, 3*6, 4}; tabNotes = new int[8]; int l1 = tab.length; // l1 = 3 int l2 = tabNots.length; // l2 = 8 int e = tabNotes[8];  /* La compilation produit le message suivant : ArrayIndexOutOfBoundsException */
Exemple de tableau de chaînes: Paramètres de la ligne de commande class TestArguments { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); } } $javac TestArguments $ java TestArguments arg1 arg2  affichera arg1 arg2
Tableaux d’objets Les éléments d’un tableau peuvent être d’un type objet. Attention:  Il faut créer les objets avant de les utiliser. Considérons l’exemple de la classe Etudiant.  Etudiants [] etudiantSMI = new Etudiant[100];  // Chaque élément du tableau contient une référence vers un objet de type Etudiant etudiantSMI[0].setCNE(11225467);  // setCNE(int cne) est une méthode de la classe Etudiant . etudianSMI[0].codeNatEtudiant = cne; // Erreur: etudiantSMI[0] est objet de type Etudiant, donc il faut le créer avant de l’utiliser Etudiant [] etudiantSMI = new Etudiant[100];  // Chaque élément du tableau est une référence à un objet de type Etudiant   etudiantSMI[0] = new Etudiant();  //  Création de l’objet etudiantSMI[0] etudiantSMI[0].setCNE(11225467);
Affectation de Tableaux : Java permet de manipuler globalement les tableaux par affectation de leurs références Soient t1 et t2 deux tableaux t1=t2;  // La référence contenue dans t2 est affectée à t1 Maintenant t1 et t2 désignent le même objet tableau qui était  initialement référencé par t2  t1[2]=3;  // t2[2] vaut aussi 3  t2[2]=3.  t2[4]=6;  // t1[4] vaut aussi 6  t1[4]=6;  Attention:  Si on veut copier uniquement les valeurs de t2 dans t1, alors dans ce cas on peut faire une copie élément par élément
Les tableaux en argument d’une méthode: Le passage des tableaux comme paramètres des méthodes se fait par  référence  (comme les objets) et non par  copie  (comme les types les types primitifs) La méthode agit directement sur le tableau et non sur sa copie
Tableaux à plusieurs dimensions Déclaration int[][] notes;  // c’est un tableau de tableaux Chaque élément du tableau contient une référence vers un tableau Création:  Il faut donner au moins les premières dimensions notes = new int[30][3];  // Tableau de 30 étudiants, chacun //  des 30 étudiants  a au plus 3  notes notes = new int[30][];  //  Chacun des 30 étudiants a un  // nombre de notes variable
Déclaration, création et initialisation int[][] notes = { {10, 11, 9},  // 3 notes   {15, 8},  // 2 notes . . . }; Affectation notes[10][2] = 12;
Exemple int[][] t; t = new int[2][]; int[] t0 = {0, 1}; t[0]= t0; // t[0] est un tableau  t[1] = new int[] {2, 3, 4, 5};  // Déclaration et initialisation  for (int i = 0; i < t.length; i++) { for (int j = 0; j < t[i][].length; j++) { System.out.print(t[i][j] + &quot;; &quot;); } System.out.println(); }
Ch. IV. Héritage L'héritage est une notion fondamentale en Java et de manière générale dans les langages de programmation par Objets.  Il permet de créer des classes dérivées (classes qui héritent) par combinaison de classes déjà existantes (classes de base) sans toucher au code source de la classe de base (on a seulement besoin du code compilé de la classe de base).
La classe dérivée: se comporte comme la classe de base mais avec quelques différences.  on a seulement besoin du code compilé de   la clase de base. On peut par exemple: –  ajouter de nouvelles méthodes –  adapter (modifier) certaines méthodes
Syntaxe:   class  <ClasseDerivee>  extends  <ClasseDeBase>  Interprétation:   Permet de définir un lien d'héritage entre deux classes: La classe <ClasseDeBase> est le nom de la classe de base. Elle s'appelle une  classe mère , une  classe parente  ou une  super-classe . Le mot clef  extends   indique la classe mère : La classe <ClasseDerivee> est le nom de la classe dérivée. Elle hérite de la classe < ClasseDeBase > . On  l'appelle une  classe fille  ou une  sous-classe Remarque:   Par défaut il n’y a pas de  extends   dans la définition d’une classe: une classe hérite de la classe  Object Un objet de la classe dérivée ClassDerivee accède aux membres publics de sa classe de base ClasseDeBase
Exemple class  FormeGeometrique{ //  classe mère // Définition des attributs et des méthodes } class  Point  extends  FormeGeometrique {  //  classe dérivée // Définition de nouveaux attributs (propres à la classe Point) // Définition de nouvelles méthodes (propres à la classe Point) // Modification des méthodes qui sont déjà définies dans la classe mère // Point hérite des méthodes et attributs de la superclasse FormeGeometrique } class  Cercle  extends  Point {   Définition de nouveaux attributs (propres à la classe Cercle) // Définition de nouvelles méthodes (propres à la classe Cercle) // Modification des méthodes qui sont déjà définies dans la classe mère // Cercle hérite des méthodes et attributs de la superclasse Point }
Une instance (un objet) d’une classe dérivée peut faire appelle  (accès depuis l’extérieur) Aux méthodes et aux membres publics de la classe  dérivée  Aux méthodes et membres publics de la classe de  base De même (pour l’accès depuis l’intérieur) Une méthode d’une classe dérivée a accès aux membres publics de sa classe de base Une méthode d’une classe dérivée n’a pas accès aux membres privées de sa classe de base
Quand on écrit la classe <ClasseDerivee> on doit seulement: écrire le code (variables ou méthodes) lié aux nouvelles possibilités: offrir de nouveaux services. redéfinir certaines méthodes: enrichir les services rendus par une classe.
Lorsqu'une classe hérite d'une autre classe Elle bénéficie automatiquement des définitions des attributs et des méthodes de la classe mère.  Elle peut y ajouter ses propres définitions. ajouter des variables, des méthodes et des constructeurs. redéfinir des méthodes: exactement le même nom et la même signature. surcharger des méthodes: même nom mais pas les mêmes arguments (signature).
Remarques2:   Java ne permet pas l’héritage multiple: chaque classe a une et une seule classe mère dont elle hérite les variables et les méthodes.  C++ permet l’héritage multiple.
Construction des classes dérivée   Lorsqu'on construit une instance de  ClasseDerivee , on obtient un objet dont une partie est construite grâce à la définition de  ClasseDerivee  et une partie grâce à la définition de la super­classe  ClasseDeBase . - En Java, le constructeur de la classe drivée doit prendre en  charge l’intégralité de la construction de l’objet.     Le constructeur de la classe dérivée doit faire appel au constructeur de la classe de base en appelant explicitement la méthode super() ainsi que la liste des paramètres appropriés.  Remarque:  l’appel du constructeur de la super classe (appel de la méthode super()) doit être la première instruction dans la définition du constructeur de la classe dérivée.
Exemple 1:   class  ClasseDeBase{    public  ClasseDeBase(int i) {  // constructeur de la classe de base System.out.println (&quot; Classe de Base:  &quot; + i);   }  }  class  ClasseDerivee1  extends  ClasseDeBase {    public  ClasseDerivee1(int i, int j) {  // constructeur de la classe dérivée 1  super(i+j);  // appel du constructeur ClasseDeBase   System.out.println (&quot; Classe dérivée1:  &quot; + i+ &quot; , &quot;+j); } }  class  ClasseDerivee2  extends  ClasseDerivee1{    public  ClasseDerivee2(int i) { // constructeur de la classe dérivée 2 super(i,i);  // appel du constructeur ClasseDerivee1   System.out.println(&quot; Classe dérivée2:  &quot; + i); }  }
public class  TestHeritage{  public static void main (String args[])   {    ClasseDerivee2 a= new  ClasseDerivee2(7); } } Sortie:     Classe de Base :  14   Classe dérivée1:  7  ,  7   Classe dérivée2:  7
Exemples des cas possibles: Exemple 1:   class  ClasseDeBase{    ClasseDeBase(arguments) { … } …   }  class  ClasseDerivee  extends  ClasseDeBase {  // Pas de constructeur … . }  On obtient une erreur de compilation. Un constructeur de la classe dérivée doit être défini est qui doit appeler le constructeur de la classe de base.
Exemple2:   class  ClasseDeBase{    ClasseDeBase(arguments) { // constructeur de la classe de base … }  }  class  ClasseDerivee  extends  ClasseDeBase {    ClasseDerivee(arguments) { // constructeur de la classe de base //  l’appel de super () est obligatoire sinon une erreur   … . } }
Exemple 3:   class  ClasseDeBase{    ClasseDeBase(arguments) {  // constructeur de la classe de base … } ClasseDeBase() { // constructeur sans paramètre de la classe de base … }  }  class  ClasseDerivee  extends  ClasseDeBase {    ClasseDerivee(arguments) { // constructeur de la classe dérivée // l’appel de super () n’est pas obligatoire.  // si  super()  n’est pas appelé explicitement,  // le constructeur par défaut de ClasseDeBase est appelé  … . } }
Exemple 4:   class  ClasseDeBase{    // Pas de constructeur … }  class  ClasseDerivee  extends  ClasseDeBase {  // Pas de constructeur … . }  La création d’un objet de type ClasseDerivee entraîne l’appel de constructeur par défaut qui appelle le constructeur par défaut de la ClasseDeBase.
Exemple pratique:   class  ClasseDeBase{    ClasseDeBase() { System.out.println(&quot; Classe de Base:  &quot;);   }  }  class  ClasseDerivee1  extends  ClasseDeBase {    ClasseDerivee1() {    //  Appel implicite du constructeur par défaut de ClasseDeBase   System.out.println(&quot; Classe dérivée1:  &quot;); } }  class  ClasseDerivee2  extends  ClasseDerivee1{    ClasseDerivee2() {  //  Appel implicite du constructeur par défaut de ClasseDerivee1     System.out.println(&quot; Classe dérivée2:  &quot; ); }  }
public class  TestHeritage{  public static void  main (String args[])  {    ClasseDerivee2 a=new ClasseDerivee2(); } } Sortie:     Classe de Base :    Classe dérivée1:    Classe dérivée2:
Résumé: Si on n'appelle pas le constructeur de la super­classe, le constructeur par défaut est utilisé si: aucun constructeur n’est défini au moins un constructeur sans paramètre est défini sinon le compilateur déclare une erreur
Notion de la Redéfinition   Ne pas confondre  redéfinition  et  surcharge  des méthodes : –  on redéfinit une méthode quand une nouvelle méthode a le même nom et la même signature qu’une méthode héritée de la classe mère. –  on surcharge une méthode quand une nouvelle méthode a le même nom, mais pas la même signature, qu’une autre méthode de la même classe
­  Lorsqu'un attribut ou une méthode ont été définis dans une classe et sont redéfinis dans une classe dérivée (qui en hérite), les éléments visibles sont ceux redéfinis dans la classe dérivée. Les éléments de la classe de base (héritée) sont alors masqués.  class  Rect  extends  ObjetGraphique {  void move(int dx, int dy);  ...  }  class  Cercle  extends  ObjetGraphique{  void move(int dx, int dy);  ...  }
­ On peut avoir les mêmes méthodes  move()  dans des classes héritant les unes des autres. Dans ce cas, c'est la classe la plus dérivée de l'objet qui détermine la méthode à exécuter, sans que le programmeur ait à faire des tests sur le type de l'objet à traiter.
C* F E D* B A* *: signifie la définition ou la redéfinition d’une méthode f. Class A: méthode de A Classe B: méthode de A Classe D: méthode de D Classe E: méthode de A Classe C: méthode de C Classe F: méthode de C
­ la redéfinition d'une méthode d'une classe consiste à fournir dans une sous­classe une nouvelle implémentation de la méthode. Cette nouvelle implémentation masque alors complètement celle de la super­classe  ­ Grâce au mot­clé super, la méthode redéfinie dans la sous­classe peut réutiliser du code écrit dans la méthode de la super­classe, qui n'est plus visible autrement. ­ super à un sens uniquement dans une méthode (comme le mot­clé this).
class  Point {  public void  afficher(){  System.out.pritln (&quot; je suis en &quot;+ x +&quot; et &quot; +y);  }  private   int  x,y; }  class  PointCol  extends  Point {  public void  afficher() {  // redéfinition de la méthode afficher super. afficher();  // appel de la méthode afficher de la classe de base  System.out.println  (&quot; et ma couleur est:  &quot;+ couleur);   }  private byte  couleur; }
Soit une classe  B  qui hérite d'une classe  A.  Soit f une méthode définie dans A. Dans une méthode d'instance g ()  de  B ,  super.  sert à désigner un membre de  A. par exemple:  super.f()  désigne la méthode f() de  A Attention:  On ne peut remonter plus haut que la classe mère pour récupérer une méthode redéfinie : –  pas de «  super.super. »
Exemple: class A { public void f(){ System.out.println(&quot;Je suis dans la classe de base A&quot;); } } class B extends A { public void g(){ super.f();  // désigne la méthode f() de la classe mère A System.out.println(&quot;je suis aussi dans la class derivee B&quot;); } } public class TestRedefinition { public static void main (String args[])  {  B b = new B(); b.g(); }   }
Héritage (Suite) Une Classe  final  ne peut pas avoir de classes filles La redéfinition d'une méthode  public  ne peut être  private Une méthode  final   ne peut pas être redéfinie
Sous-type Le type  B  est un sous-type de  A  si on peut affecter une expression de type  B  dans une variable de type  A. Les type primitifs   int  est un sous type de  float float  est un sous type de  double …  Les objets Les sous-classes d’une classe A sont des sous types de A. Dans ce cas on peut écrire: A a = new B(…);   // la variable a est de type A, alors que    // l’objet référencé par a est de type B. A aa; B b=new B(); aa=b;  // aa de type A, référence un objet de type B
Définitions: La classe (ou le type) réelle  de l’objet est la classe du constructeur qui a créé l’objet Exemple:   Soit B une sous classe de A A a = new B(…); // B est la classe (type) réelle de l’objet a Le type (la clase) déclaré  de l’objet est le type qui est donné au moment de la déclaration de la variable qui référence l’objet. Exemple:  Soit B une sous classe de A A a = new B(…); // A est le type déclaré de l’objet a
Cas des tableaux   Soit B une classe qui hérite de la classe A, alors on peut écrire : A[] tab = new B[5];  Attention:  Dans tab[] il faut les valeurs de type réel et non celles du type déclaré (c’est à dire des valeur de type B et non de type A). Par exemple, si on a les instructions suivantes:  A[] tab = new B[5]; A a = new A(); tab[0] = a; Passe à la compilation mais provoquera une erreur à l’exécution car tab[0] reçoit une valeur de type A et non une valeur de type B
Polymorphisme Exemple introductif: Considérons l’exemple suivant où B est une classe  qui hérite de la classe A. Soient f() une méthode qui reédinie dans B et g une méthode définie dans A. On suppose que  class  A { public void  f(){   System.out.println(&quot;Methode f(): Classe de base A&quot;); } public void  g(){   System.out.println(&quot;Methode g(): Classe de base A&quot;); } } class  B  extends  A {  public   void  f(){ System.out.println(&quot;Methode f(): Classe B derivee de A&quot;); public   void  h(){ System.out.println(&quot;Methode h(): Classe B derivee de A&quot;); } }
A a=new A();  B b = new B(); a.f();  // appelle la méthode définie dans A  a=b;  // A a = new(B); a.f();  // appelle la méthode définie dans B a.g(); // appelle la méthode définie dans A b.g(); // appelle la méthode définie dans A Il faut noter que la même écriture a.f(); peut correspondre à des appels différents de la méthode f(). Ceci est réalisé grâce au polymorphisme. Le Polymorphisme veut dire que le même service peut avoir un comportement différent suivant la classe dans laquelle il est utilisé. C’est un concept fondamental de la programmation objet, indispensable pour une utilisation efficace de l’héritage
Attention c’est important: Si on a: B b = new B(); b.h();  // appelle la méthode h() définie dans B  A a=new B(); a.h();  // erreur à la compilation même si la classe réelle possède  //  la méthode h(). En effet la   classe déclarée (classe A)  //  ne ossède pas la méthode h(). En effet, en Java, dès la compilation on doit garantir l’existence de la méthode appelée typage statique) : la  classe déclarée de l’objet  qui reçoit le message (ici la classe A ou une de ces classes ancêtres (polymorphisme)) doit posséder cette méthode ().
Le polymorphisme est obtenu grâce au mécanisme de la liaison retardée (tardive) «  late binding  »: la méthode qui sera exécutée est déterminée seulement à l’exécution, et pas dès la compilation par le type réel de l’objet qui reçoit le message (et pas par son type déclaré)
Mécanisme de la liaison retardée: cas des méthodes redéfinies Soit D la classe réelle d’un objet d (D est la classe du constructeur qui a créé l’objet d) et  soit A la classe de déclaration de l’objet d (A d = new D();). Si on a l’instruction:  d.f();   quelle méthode f() sera appelée ? 1.  Si la méthode f() n’est pas définie dans une classe ancêtre de la classe de déclaration (classe A) alors erreur de compilation.  2.  Si non  Si la méthode f()  est redéfinie  dans la classe D, alors c’est cette méthode qui sera exécutée Sinon, la recherche de la méthode f() se poursuit dans la classe mère de D, puis dans la classe mère de cette classe mère, et ainsi de suite, jusqu’à trouver la définition d’une méthode f() qui sera alors exécutée.
La méthode appelée ne dépend que du type réel de l’objet et non du type déclaré.  Soit B une classe qui hérite de la classe A, et soit  f() une méthode définie dans A et redéfinie dans B.  Si on a:  A a = new B();  a.f();  Alors la méthode f() appelée est celle définie dans B. Si C hérite de B et si la méthode f() est redéfinie dans C, alors si on a: A a = new C();  // Ok car C hérite de B qui hérite de A a.f();  La méthode appelée est celle définie dans C.
Utilités du Polymorphisme: Le polymorphisme permet d’éviter les codes qui comportent de nombreux embranchements et tests. Exemple Considérons une classe FormeGeometrique. Supposons que les classes Rectangle et Cercle héritent de la super classe FormeGeometrique. Dans un tableau hétérogène, on ranges des objets de type Rectangle, Cercle. Ensuite on affiche le contenu du tableau
Exemple  class  FormeGeometrique { public void  dessineRectangle() {}  // méthode vide  public void  dessineCercle() {}  // méthode vide } class  Rectangle extends FormeGeometrique { public void  dessineRectangle() { System.out.println(&quot;Je suis un rectangle &quot;); } } class  Cercle extends FormeGeometrique { public void  dessineCercle() { System.out.println(&quot;Je suis un cercle .... &quot;); } }
public class  TestFigPoly { public static void  main(String[] args) {   FormeGeometrique [] figures = new FormeGeometrique[3]; figures[0]= new  Rectangle(); figures[1]= new  Cercle(); figures[2]= new  Cercle(); for (int i=0; i < figures.length; i++) { if (figures[i]  instanceof  Rectangle) figures[i].dessineRectangle(); else if (figures[i]  instanceof  Cercle) figures[i].dessineCercle(); } } } instanceof:  Soit b est une instance d'une classe B alors ( b instanceof A ) retourne  true  si B est une sous classe de A. En particulier ( b instanceof B ) retourne  true.
Inconvénients dans le code précédent: Si on veut rajouter une nouvelle forme géométrique par exemple, triangle alors on est obliger de: changer dans le code source aux niveaux définition de la classe  (rajouter la méthode vide  public void  dessineTriangle() {}) Rajouter un branchement pour la forme Triangle Si on traite plusieurs formes géométrique, alors le code comportera plusieurs tests.  En exploitant le polymorphisme, on peut améliorer le code précédent  Eviter les tests Rendre le code extensible: rajouter de nouvelles sous-classes sans toucher au code existant)
L’exemple peut être réécrit de la manière suivante en exploitant le polymorphisme class  FormeGeometrique { public void  dessineFigure() {}  // méthode vide  } class  Rectangle extends FormeGeometrique { public void  dessineFigure() { System.out.println(&quot;Je suis un rectangle &quot;); } } class  Cercle extends FormeGeometrique { public void  dessineFigure() { System.out.println(&quot;Je suis un cercle .... &quot;); } }
public class  TestFigPoly { public static void  main(String[] args) { FormeGeometrique [] figures = new FormeGeometrique[3]; figures[0] =  new  Rectangle(); figures[1] =  new  Cercle(); figures[2] =  new  Cercle(); for (int i=0; i < figures.length; i++) figures[i].dessineFigure();  // pas besoin de spécifier quelle forme } }
Un autre exemple d’exploitation du Polymorphisme:  Considérons l’exemple précédent, en supposant que le rectangle et le cercle sont caractérisés par des champs privés qui désignent: La position dans le plan (position du centre) La longueur et la largeur pour le rectangle Le rayon pour le Cercle.  Considérons un tableau hétérogène qui contient des formes géométriques différentes: rectangles, cercles, ...  Le but et d’afficher le type de la forme géométrique et ses caractéristiques
1 ère  solution: class  FormeFigure { public void  dessineFigure() {}  } class  Rectangle extends FormeFigure { public  Rectangle(int x, int y, int longueur, int largeur) {  // centre (x,y) this.x=x; this.y=y;  this.largeur=largeur; this.longueur=longueur; } public void  dessineFigure() {   System.out.println(&quot; Je suis un Rectangle de longueur &quot; +longueur +&quot; et de largeur &quot; + largeur);   System.out.println(&quot;  ma position dans le plan est  (&quot;  + x + &quot; ,&quot; + y + &quot;)&quot; ); } private int  x,y; private   int  largeur, longueur; }
class  Cercle extends FormeFigure { public  Cercle(int x, int y, int rayon){  // centre (x,y)   this.x=x; this.y=y; this.rayon=rayon; } public void  dessineFigure(){ System.out.println(&quot; Je suis un cercle de Rayon  &quot; + rayon);   System.out.println(&quot;  ma position dans le plan est  (&quot;  + x + &quot; ,&quot; + y + &quot;)&quot; ); } private int  x,y;  private  int rayon; }
public class  TestFigPolySuite {   public static void  main(String[] args) {   FormeFigure [] figures = new FormeFigure[2];   figures[0]=new Rectangle(1,2,15,6);   figures[1]=new Cercle(0,0,4);   for (int i=0; i < figures.length; i++) figures[i].dessineFigure(); } }
2 ème  solution  :  on ne redéfinie pas la position dans le plan qui est la même pour toutes les formes géométrique. class  FormeFigure { public  FormeFigure(int x, int y) { // constructeur this.x=x;  this.y=y; } public void  dessineFigure() {   afficheMonIdentite(); System.out.println(&quot; ma position dans le plan est  (&quot; + x + &quot; ,&quot; + y + &quot;)&quot; );  }  public void  afficheMonIdentite(){}; // méthode vide private  int x,y; }
class  Rectangle extends FormeFigure { public  Rectangle(int x, int y, int longueur, int largeur) {  // centre (x,y) super(x,y);  this.largeur=largeur; this.longueur=longueur; } public void  afficheMonIdentite() {   System.out.println(&quot; Je suis un Rectangle de longueur &quot; +longueur +&quot; et de largeur &quot; + largeur); } private  int largeur, int longueur; } class  Cercle extends FormeFigure { public  Cercle(int x, int y, int rayon){  // centre (x,y)   super(x,y); this.rayon=rayon; } public void  afficheMonIdentite() { System.out.println(&quot; Je suis un cercle de Rayon  &quot; + rayon); } private  int rayon; }
public class  TestFigPolySuite { public static void  main(String[] args) {   FormeFigure [] figures = new FormeFigure[2];   figures[0]=new Rectangle(1,2,15,6);   figures[1]=new Cercle(0,0,4);   for (int i=0; i < figures.length; i++) figures[i].dessineFigure(); // la méthode afficheMonIdentite() appelée est celle définie dans la classe //réelle de l’objet et non celle définie dans la classe de déclaration  } }
Cast (transtypage) : conversions de classes Le «  cast »  est le fait de forcer le compilateur à considérer un objet comme étant d’un type qui n’est pas le  type déclaré ou réel de l’objet En Java, les seuls  casts  autorisés entre classes sont les  casts  entre classe mère et classes filles
Syntaxe Pour caster un objet en classe  A  :  (C) o; Exemple : FormeFigure a = new FormeFigure(); Rectangle r = (Rectangle) a; FormeFigure b; (Rectangle) b = r;
UpCast  : classe fille -> classe mère Upcast  : un objet est considéré comme une instance d’une des classes ancêtres de sa classe réelle Il est toujours possible de faire un  upcast  car tout objet peut être considéré comme une instance d’une classe ancêtre Le  upcast  est souvent implicite
DownCast  : classe mère -> classe fille Downcast  : un objet est considéré comme étant d’une classe fille de sa classe de déclaration Toujours accepté par le compilateur Mais peut provoquer une erreur à l’exécution ; à l’exécution il sera vérifié que l’objet est bien de la classe fille Un  downcast  doit toujours être explicite
Classes abstraites Une classe abstraite ( abstract class ) est une classe déclarée avec le mot clé  abstract class .  Par exemple:   abstract class  A {  …    }  Dans une classe abstraite on peut trouver: des champs, des méthodes et des  méthodes abstraites
Une méthode est abstraite, lorsqu’on la déclare sans donner son implémentation: on ne fournit que le type de la valeur de retour et la signature (l’entête de la méthode). Les méthodes abstraite sont déclarée avec le mot clè  abstract . Exemple: abstract void  f( int  i,  float  x); abstract double  g(); La méthode peut être implémentée par les classes filles.
On peut créer  une référence  sur un objet de type A (une classe abstraite) mais il est interdit de créer  une instance (un objet)  d’une classe abstraite A a;  // autorisé A a = new A(); // n’est pas autorisé. Si B hérite de A alors on peut écrire: A a = new B(); Une méthode  static  ne peut être abstraite (car on ne peut redéfinir une méthode  static ) Une classe qui contient au moins une méthode abstraite est automatiquement abstraite Une méthode déclarée abstraite doit obligatoirement être déclarée public.
Intérêt des classe abstraites: la classe mère définit la structure globale  d’un algorithme elle laisse aux classes filles le soin de définir des points bien précis de l
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008
Cours java smi 2007 2008

Contenu connexe

Tendances

Chap 03 poo en java partie1
Chap 03 poo en java partie1Chap 03 poo en java partie1
Chap 03 poo en java partie1
Yassine Badri
 
Chapitre 4 persistance des donnees
Chapitre 4  persistance des donneesChapitre 4  persistance des donnees
Chapitre 4 persistance des donnees
Amir Souissi
 
POO
POOPOO
Chap 03 poo en java partie2
Chap 03 poo en java partie2Chap 03 poo en java partie2
Chap 03 poo en java partie2
Yassine Badri
 
Java chap 04 surcharge des méthodes [mode de compatibilité]
Java chap 04 surcharge des méthodes [mode de compatibilité]Java chap 04 surcharge des méthodes [mode de compatibilité]
Java chap 04 surcharge des méthodes [mode de compatibilité]
Yassine Badri
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux java
Ines Ouaz
 
JAVA Chapitre7
JAVA Chapitre7JAVA Chapitre7
JAVA Chapitre7
Mohamed Ferchichi
 
Csharp2 : classes et objets
Csharp2 : classes et objetsCsharp2 : classes et objets
Csharp2 : classes et objets
Abdoulaye Dieng
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en Python
Abdoulaye Dieng
 
Les Classe en Java
Les Classe en JavaLes Classe en Java
Les Classe en Java
Wiki Info Systeme
 
Héritage et polymorphisme- Jihen HEDHLI
Héritage et polymorphisme- Jihen HEDHLIHéritage et polymorphisme- Jihen HEDHLI
Héritage et polymorphisme- Jihen HEDHLI
JihenHedhli1
 
JAVA Chapitre6
JAVA Chapitre6JAVA Chapitre6
JAVA Chapitre6
Mohamed Ferchichi
 
Cours c++
Cours c++Cours c++
Cours c++
Nahla BelHaj
 
Cours java smi_2011_2012_partie_i_29_octobre_2011
Cours java smi_2011_2012_partie_i_29_octobre_2011Cours java smi_2011_2012_partie_i_29_octobre_2011
Cours java smi_2011_2012_partie_i_29_octobre_2011
yassine kchiri
 
JAVA Chapitre8
JAVA Chapitre8JAVA Chapitre8
JAVA Chapitre8
Mohamed Ferchichi
 
c# programmation orientée objet (Classe & Objet)
c# programmation orientée objet (Classe & Objet)c# programmation orientée objet (Classe & Objet)
c# programmation orientée objet (Classe & Objet)
Mahfoud EL HOUDAIGUI
 
Exceptions
ExceptionsExceptions
Exceptions
Axel KAMALAK
 

Tendances (19)

Chap 03 poo en java partie1
Chap 03 poo en java partie1Chap 03 poo en java partie1
Chap 03 poo en java partie1
 
Chapitre 4 persistance des donnees
Chapitre 4  persistance des donneesChapitre 4  persistance des donnees
Chapitre 4 persistance des donnees
 
POO
POOPOO
POO
 
Chap 03 poo en java partie2
Chap 03 poo en java partie2Chap 03 poo en java partie2
Chap 03 poo en java partie2
 
Cours java
Cours javaCours java
Cours java
 
Java chap 04 surcharge des méthodes [mode de compatibilité]
Java chap 04 surcharge des méthodes [mode de compatibilité]Java chap 04 surcharge des méthodes [mode de compatibilité]
Java chap 04 surcharge des méthodes [mode de compatibilité]
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux java
 
JAVA Chapitre7
JAVA Chapitre7JAVA Chapitre7
JAVA Chapitre7
 
Csharp2 : classes et objets
Csharp2 : classes et objetsCsharp2 : classes et objets
Csharp2 : classes et objets
 
Introduction à l’orienté objet en Python
Introduction à l’orienté objet en PythonIntroduction à l’orienté objet en Python
Introduction à l’orienté objet en Python
 
TD Java POO
TD Java POO TD Java POO
TD Java POO
 
Les Classe en Java
Les Classe en JavaLes Classe en Java
Les Classe en Java
 
Héritage et polymorphisme- Jihen HEDHLI
Héritage et polymorphisme- Jihen HEDHLIHéritage et polymorphisme- Jihen HEDHLI
Héritage et polymorphisme- Jihen HEDHLI
 
JAVA Chapitre6
JAVA Chapitre6JAVA Chapitre6
JAVA Chapitre6
 
Cours c++
Cours c++Cours c++
Cours c++
 
Cours java smi_2011_2012_partie_i_29_octobre_2011
Cours java smi_2011_2012_partie_i_29_octobre_2011Cours java smi_2011_2012_partie_i_29_octobre_2011
Cours java smi_2011_2012_partie_i_29_octobre_2011
 
JAVA Chapitre8
JAVA Chapitre8JAVA Chapitre8
JAVA Chapitre8
 
c# programmation orientée objet (Classe & Objet)
c# programmation orientée objet (Classe & Objet)c# programmation orientée objet (Classe & Objet)
c# programmation orientée objet (Classe & Objet)
 
Exceptions
ExceptionsExceptions
Exceptions
 

En vedette

La vraie vie des Franciliens
La vraie vie des FranciliensLa vraie vie des Franciliens
La vraie vie des Franciliens
Ipsos France
 
L’Importance Du Look
L’Importance Du LookL’Importance Du Look
L’Importance Du Look
dinahbeckman
 
Descriptions
DescriptionsDescriptions
Descriptions
advillage
 
Je me présente
Je me présenteJe me présente
Je me présente
okram1
 
Placage de la lentille lunettes de soleil prada pas cher
Placage de la lentille lunettes de soleil prada pas cherPlacage de la lentille lunettes de soleil prada pas cher
Placage de la lentille lunettes de soleil prada pas cher
Joe Gowey
 
Comparatif des adj et adv
Comparatif des adj et advComparatif des adj et adv
Comparatif des adj et adv
MmeOnsdorff
 
ESIEE intervention sur le theme du web 2.0 - 2010
ESIEE intervention sur le theme du web 2.0 - 2010ESIEE intervention sur le theme du web 2.0 - 2010
ESIEE intervention sur le theme du web 2.0 - 2010
Spectrum Groupe
 
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULgGénie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
Réseau LIEU (Liaison Entreprises-Universités)
 
Langage C
Langage  CLangage  C
Langage C
jwilili
 
Données Ouvertes : mode d'emploi ?
Données Ouvertes : mode d'emploi ?Données Ouvertes : mode d'emploi ?
Données Ouvertes : mode d'emploi ?
mondeca
 
Nouveau microsoft word document
Nouveau microsoft word documentNouveau microsoft word document
Nouveau microsoft word document
karimfpk
 
Les sources energétiques de la resynthese de l'atp a  la contraction muscul...
Les sources energétiques   de la resynthese de l'atp a  la contraction muscul...Les sources energétiques   de la resynthese de l'atp a  la contraction muscul...
Les sources energétiques de la resynthese de l'atp a  la contraction muscul...
IRMSHN276
 
Metabolisme des lipides
Metabolisme des lipidesMetabolisme des lipides
Metabolisme des lipides
killua zoldyck
 
Brochure Meca-19102016-bd
Brochure Meca-19102016-bdBrochure Meca-19102016-bd
Brochure Meca-19102016-bd
Camille Volant
 
Protection des métaux contre la corrosion
Protection des métaux contre la corrosionProtection des métaux contre la corrosion
Protection des métaux contre la corrosion
CHTAOU Karim
 
TRANSITION METALS
TRANSITION METALSTRANSITION METALS
TRANSITION METALS
Drix78
 
Droit Et Deontologie Partie 1 Isfsc Sept 2009
Droit Et Deontologie Partie 1 Isfsc Sept 2009Droit Et Deontologie Partie 1 Isfsc Sept 2009
Droit Et Deontologie Partie 1 Isfsc Sept 2009
Prof. Jacques Folon (Ph.D)
 
Rugovia® - Les revêtements minces pour toutes les circonstances
Rugovia® - Les revêtements minces pour toutes les circonstancesRugovia® - Les revêtements minces pour toutes les circonstances
Rugovia® - Les revêtements minces pour toutes les circonstances
Eurovia_Group
 

En vedette (20)

La vraie vie des Franciliens
La vraie vie des FranciliensLa vraie vie des Franciliens
La vraie vie des Franciliens
 
L’Importance Du Look
L’Importance Du LookL’Importance Du Look
L’Importance Du Look
 
Descriptions
DescriptionsDescriptions
Descriptions
 
Je me présente
Je me présenteJe me présente
Je me présente
 
Placage de la lentille lunettes de soleil prada pas cher
Placage de la lentille lunettes de soleil prada pas cherPlacage de la lentille lunettes de soleil prada pas cher
Placage de la lentille lunettes de soleil prada pas cher
 
Comparatif des adj et adv
Comparatif des adj et advComparatif des adj et adv
Comparatif des adj et adv
 
Description Physique
Description PhysiqueDescription Physique
Description Physique
 
ESIEE intervention sur le theme du web 2.0 - 2010
ESIEE intervention sur le theme du web 2.0 - 2010ESIEE intervention sur le theme du web 2.0 - 2010
ESIEE intervention sur le theme du web 2.0 - 2010
 
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULgGénie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
Génie chimique - Nanomatériaux, Catalyse, Electrochimie - ULg
 
Langage C
Langage  CLangage  C
Langage C
 
Données Ouvertes : mode d'emploi ?
Données Ouvertes : mode d'emploi ?Données Ouvertes : mode d'emploi ?
Données Ouvertes : mode d'emploi ?
 
Electolyse cu-br
Electolyse cu-brElectolyse cu-br
Electolyse cu-br
 
Nouveau microsoft word document
Nouveau microsoft word documentNouveau microsoft word document
Nouveau microsoft word document
 
Les sources energétiques de la resynthese de l'atp a  la contraction muscul...
Les sources energétiques   de la resynthese de l'atp a  la contraction muscul...Les sources energétiques   de la resynthese de l'atp a  la contraction muscul...
Les sources energétiques de la resynthese de l'atp a  la contraction muscul...
 
Metabolisme des lipides
Metabolisme des lipidesMetabolisme des lipides
Metabolisme des lipides
 
Brochure Meca-19102016-bd
Brochure Meca-19102016-bdBrochure Meca-19102016-bd
Brochure Meca-19102016-bd
 
Protection des métaux contre la corrosion
Protection des métaux contre la corrosionProtection des métaux contre la corrosion
Protection des métaux contre la corrosion
 
TRANSITION METALS
TRANSITION METALSTRANSITION METALS
TRANSITION METALS
 
Droit Et Deontologie Partie 1 Isfsc Sept 2009
Droit Et Deontologie Partie 1 Isfsc Sept 2009Droit Et Deontologie Partie 1 Isfsc Sept 2009
Droit Et Deontologie Partie 1 Isfsc Sept 2009
 
Rugovia® - Les revêtements minces pour toutes les circonstances
Rugovia® - Les revêtements minces pour toutes les circonstancesRugovia® - Les revêtements minces pour toutes les circonstances
Rugovia® - Les revêtements minces pour toutes les circonstances
 

Similaire à Cours java smi 2007 2008

Chapitre3 2013 POO
Chapitre3 2013 POOChapitre3 2013 POO
Chapitre3 2013 POO
Seif Eddine Attia
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVA
Aymen Bedwivski
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
Amel Morchdi
 
Java cours n° 2 - classe-objet-constructeur
Java   cours n° 2 - classe-objet-constructeurJava   cours n° 2 - classe-objet-constructeur
Java cours n° 2 - classe-objet-constructeur
Abdelwahab Naji
 
fdocuments.fr_chap-03-poo-en-java-partie1.pptx
fdocuments.fr_chap-03-poo-en-java-partie1.pptxfdocuments.fr_chap-03-poo-en-java-partie1.pptx
fdocuments.fr_chap-03-poo-en-java-partie1.pptx
TarikElMahtouchi1
 
XB-Java.ppt
XB-Java.pptXB-Java.ppt
XB-Java.ppt
RihabBENLAMINE
 
Programmation_Orientée_Objet_POO-cours.pdf
Programmation_Orientée_Objet_POO-cours.pdfProgrammation_Orientée_Objet_POO-cours.pdf
Programmation_Orientée_Objet_POO-cours.pdf
hakima29
 
22-reflection.pdf
22-reflection.pdf22-reflection.pdf
22-reflection.pdf
Patiento Del Mar
 
Introduction java
Introduction javaIntroduction java
Introduction java
Fouad Root
 
Java
JavaJava
Memo java
Memo javaMemo java
Memo java
Ghazouani Mahdi
 
POO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdfPOO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdf
YasushiTsubakik
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptx
SafaeLhr1
 
Classes et Objets.pdf
Classes et Objets.pdfClasses et Objets.pdf
Classes et Objets.pdf
AabidiHafid
 
Introspection reflection
Introspection reflectionIntrospection reflection
Introspection reflection
Eric Toguem
 
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdfCorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
hakima29
 
Cpp2 : classes et objets
Cpp2 : classes et objetsCpp2 : classes et objets
Cpp2 : classes et objets
Abdoulaye Dieng
 
PROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
PROGRAMMATION 2e GENIE PARTIE THEORIE.pptPROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
PROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
EddySHANGA
 

Similaire à Cours java smi 2007 2008 (20)

Chapitre3 2013 POO
Chapitre3 2013 POOChapitre3 2013 POO
Chapitre3 2013 POO
 
JAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVAJAVA-UIK-CHAP6-POO HERITAGE JAVA
JAVA-UIK-CHAP6-POO HERITAGE JAVA
 
Java uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 javaJava uik-chap6-poo heritage v2 java
Java uik-chap6-poo heritage v2 java
 
4711538.pptx
4711538.pptx4711538.pptx
4711538.pptx
 
Java cours n° 2 - classe-objet-constructeur
Java   cours n° 2 - classe-objet-constructeurJava   cours n° 2 - classe-objet-constructeur
Java cours n° 2 - classe-objet-constructeur
 
fdocuments.fr_chap-03-poo-en-java-partie1.pptx
fdocuments.fr_chap-03-poo-en-java-partie1.pptxfdocuments.fr_chap-03-poo-en-java-partie1.pptx
fdocuments.fr_chap-03-poo-en-java-partie1.pptx
 
XB-Java.ppt
XB-Java.pptXB-Java.ppt
XB-Java.ppt
 
Programmation_Orientée_Objet_POO-cours.pdf
Programmation_Orientée_Objet_POO-cours.pdfProgrammation_Orientée_Objet_POO-cours.pdf
Programmation_Orientée_Objet_POO-cours.pdf
 
22-reflection.pdf
22-reflection.pdf22-reflection.pdf
22-reflection.pdf
 
Introduction java
Introduction javaIntroduction java
Introduction java
 
Java
JavaJava
Java
 
Memo java
Memo javaMemo java
Memo java
 
POO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdfPOO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdf
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptx
 
Classes et Objets.pdf
Classes et Objets.pdfClasses et Objets.pdf
Classes et Objets.pdf
 
Introspection reflection
Introspection reflectionIntrospection reflection
Introspection reflection
 
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdfCorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
CorrigesDesExercices_ProgrammationOrienteeObjet_Bersini.pdf
 
Springioc
SpringiocSpringioc
Springioc
 
Cpp2 : classes et objets
Cpp2 : classes et objetsCpp2 : classes et objets
Cpp2 : classes et objets
 
PROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
PROGRAMMATION 2e GENIE PARTIE THEORIE.pptPROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
PROGRAMMATION 2e GENIE PARTIE THEORIE.ppt
 

Cours java smi 2007 2008

  • 1. Programmation Orientée Objet en Java El Mostafa DAOUDI 1,2 1 École Nationale des Sciences Appliquées [email_address] 2 Laboratoire LaRI, Faculté des Sciences, Département de Mathématiques et d’Informatique, FSO [email_address] Septembre 2007
  • 2. Ch I. JAVA: les bases I. Généralités sur les objets Un objet est une variable améliorée: il stocke les données, mais on peut effectuer des requêtes sur cet objet (on demande à l’objet de faire des opérations sur lui-même), en envoyant un message à cet objet. Ceci est équivalent à un appel de fonction. Chaque objet à son espace mémoire: la simplicité des objet mis en œuvre, cache la complexité des programme. Chaque objet a un type précis: c’est-à-dire chaque objet est une instance (variable) d’une class (type) Un programme est ensemble d’objets qui s’envoient des messages.
  • 3. II. Les bases à connaître Java est un langage orienté objet: l'entité de base de tout code Java est la classe Sa syntaxe est proche du langage C Il est fourni avec le JDK (Java Developpment Kit) Outils de développement Ensemble de paquetages très riches et très variés Multi-tâches ( threads ) Portable grâce à l’exécution par une machine virtuelle
  • 4. En Java, tout se trouve dans une classe . Il ne peut y avoir de déclarations ou de code en dehors du corps d'une classe. La classe elle même ne contient pas directement du code. Elle contient des déclarations de variables globales, que l'on appelle des ``attributs'', et des méthodes (équivalents à des fonctions). Le code se trouve exclusivement dans le corps des méthodes, mais ces dernières peuvent aussi contenir des déclarations de variables locales (visibles uniquement dans le corps de la méthode).
  • 5. III. Mon premier programme en Java Considérons le code source du programme qui affiche à l’écran Mon premier programme Java // Fichier source MonPremProg.java public class MonPremProg { // déclaration de données globales //définition des méthodes public static void main(String args[]) { // déclaration des données locales; System.out.println( &quot; Mon premier programme Java &quot; ); } }
  • 6. De manière générale, dans tout programme autonome destiné à être exécuté doit contenir une méthode particulière nommée main() définie de la manière suivante: public static void main(String args[]) { /* corps de la méthode */ } Le paramètre args de la méthode main() est un tableau d’objets de type String . Il n’est pas utilisé mais, il est exigé par le compilateur Java. La classe contenant la méthode main() doit obligatoirement être public afin que la machine virtuelle y accès. Dans l’exemple, le contenu de la classe MonPremProg est réduit à la définition d’une méthode main() .
  • 7. Un fichier source peut contenir plusieurs classes mais une seule doit être public(ici PremProg ). Le nom du fichier source est identique au nom de la classe publique qu'il contient, suivi du suffixe .java, dans l’exemple MonPremProg.java
  • 8. Compilation La compilation d’un programme Java ne traduit pas directement le code source en fichier exécutable. Elle traduit d’abord le code source en un code intermédiaire appelé « bytecode ». C’est le bytecode qui sera ensuite exécuté par une machine virtuelle (JVM ; Java Virtual Machine ). Ceci permet de rendre le code indépendant de la machine qui va exécuter le programme.
  • 9. Sun fournit le compilateur javac avec le JDK. Dans notre exemple on exécute: javac MonPremProg.java Cette compilation crée un fichier nommé « MonPremProg .class » qui contient le bytecode On peut désigner le fichier à compiler par un chemin absolu ou relatif : javac home/user2/MonPremProg.java Si un système possède une JVM il peut exécuter tous les bytecodes (fichiers .class ) compilés sur n’importe qu’ele autre système.
  • 10. Exécution du bytecode Le bytecode doit être exécuté par une JVM. Cette JVM n'existe pas ; elle est simulée par un programme qui lit les instructions (en bytecode ) du programme .class , les traduit dans le langage machine relatif à la machine sur laquelle il sera exécuté. Lance leur exécution
  • 11. Exécution avec java Dans le cas de l’environnement JDK de SUN. Pour compiler il suffit d’utiliser la commande javac : javac MonPremProg.java Pour exécuter, Sun fournit le programme java qui simule une JVM. Il suffira d’utiliser la commande: java MonPremProg qui interprète le bytecode de la méthode main() de la classe MonPremProg
  • 12. L’exécution du programme MonPremProg affiche à l’écran, comme résultat, la chaîne de caractères: Mon premier programme Java, grâce à l’instruction: System.out.println( &quot; Mon premier programme Java &quot; ); Dans le programme, une ligne qui commence avec // est un commentaire jusqu’à la fin de la ligne Une ligne qui commence avec /* est un commentaire qui peut être étalé sur plusieurs lignes, et doit terminer avec */
  • 13. III. Les classes en Java Une classe décrit un ensemble d’objets qui partagent des caractéristiques communes. On définit une classe pour représenter un problème au lieu d’utiliser un type de données pour représenter une unité de stockage dans l’ordinateur. Créer des classes (des types de données abstraites) est un concept fondamental dans la POO. On utilise les classes exactement de la même manière que les types de données prédéfinies. On peut créer des variables (objets ou instance) d’un type particulier.
  • 14. Pour créer un nouveau type d’objets de on utilise le mot clé class . Le canevas de base pour définir un nouveau type de nom NomDuType est la suivante: class NomDuType { /* Corps de la classe: instructions de définitions des méthodes et des champs */ }
  • 15. Dans la définition de la classe (corps de la classe), on met deux types d’éléments: des données membres de la classe (appelées champs) qui sont des objets de n’importe quel type. des fonctions membres de la classe (appelées méthodes).
  • 16. Exemple: UnTest est une classe (un nouveau type) qui a 3 champs : float, int et boolean . class UnTest { float x; int i; boolean b; }
  • 17. Définition des méthodes La définition de base d’une méthode ressemble à la définition d’une fonction en C. typeRetour nomMethode (/* Liste des parametres */) { /* corps de la méthode */ } nomMethode est le nom de la méthode Liste de paramètre (arguments de la méthode) donne les types et les noms des informations qu’on souhaite passer à la méthode lors de son appel. typeRetour est le type de la valeur qui est retournée par la méthode après son appel. Si la méthode ne fourni aucun résultat, alors typeRetour est remplacé par le mot clé void .
  • 18. Le mode de passage des paramètres dans les méthodes dépend de la nature des paramètres : par référence pour les objets par copie pour les types primitifs Exemple class C { void methode1 (int i){ i+=12; } void methode2 () { int i = 3; methode1(i); System.out.println( i=&quot; + i); // i=3 } }
  • 19. IV. Création et manipulation d’Objets Une fois la classe est définie, on peut créer des objets de la même manière que la déclaration des types primitif: Considérons la classe ClasseTest class ClasseTest { // corps de la classe ClasseTest } l’instruction: ClasseTest a; // déclare a comme objet (variable) de type ClasseTest
  • 20. Attention: La déclaration d’une variable de type primitif réserve un emplacement mémoire pour stocker la variable La déclaration d’un objet de type A, ne réserve pas une place mémoire pour un objet de type A, mais seulement un emplacement pour une référence à un objet de type A.  les objets sont manipulés avec des références. Exemple classique de la télécommande et la Télé. Télé = objet Télécommande = référence. Télécommande Télé Référence Objet
  • 21. Pour modifier l’objet (par exemple augmenter le son, …) on utilise la référence (la télécommande). Avoir une référence ne veut pas dire avoir l’objet (on peut avoir la télécommande sans avoir la télé).
  • 22. L’emplacement pour l’objet doit être demandé explicitement dans le programme en faisant appel à l’opérateur new . L’expression new NomClasse créée un emplacement pour un objet de type NomClasse. class NomClasse { /* Corps de la classe */ } NomClasse a = new NomClasse(); En générale: Chaque objet met ses données membres dans sa propre zone mémoire. Les données membres ne sont partagées entre les objets.
  • 23. Exemple 1: class UnTest { float x; int i; boolean b; } UnTest data = new UnTest (); // créer un objet data
  • 24. Exemple 2: Supposons qu’on veut avoir une chaîne de caractères alors on crée une référence sur String: String s; Ici on a créé la référence mais pas l’objet. Pour créer l’objet, il faut initialiser la référence s. String s= new String (&quot;cours Java&quot;); ou String s; s = new String (&quot;cours Java&quot;); Ou tout simplement ( C’est un cas particulier en Java pour les objets string) par: String s= &quot; cours Java &quot;
  • 25. Accès aux données membres Exemple 1: class UnTest { float x; int i; boolean b; } UnTest data = new UnTest (); // créer un objet data Maintenant l’objet dont la référence data existe. Pour accéder à une donnée membre on indique le nom de la référence à l’objet suivi par un point, suivi par le nom du membre dans l’objet de la manière suivante: data.i=2; // affecte 2 au membre i data.b=true; // affecte true au membre b data.x=1.2f; // affecte 1.2 au membre x.
  • 26. Appels des méthodes Les méthodes ne peuvent être créer que comme des composante d’une classe. Une méthode ne peut être appelée que pour un objet. L’appel d’une méthode pour un objet se réalise en nommant l’objet suivi d’un point suivi du nom de la méthode et de sa liste d’arguments: nomObjet.nomMethode(arg1, ….). où nomObjet : nom de la référence à l’objet nomMethode : nom de la méthode.
  • 27. Exemple: soit f () une méthode qui ne prend aucun paramètre et qui retourne une valeur de type int. Alors si on a une référence à un objet appelé a pour lequel f() peut être appelée, on peut écrire: int x = a.f() class UnTest { float x; int i; boolean b; int f() { return 10; } } UnTest a = new UnTest (); // créer un objet a; int x = a.f(); // affecte à x la valeur retournée par f
  • 28. Cas particulier des types primitifs Les types primitifs ont un traitement particulier: on n’utilise pas new , les variables (non les références) sont créées au moment de leurs déclaration. ------------------------------------------------------------------------------ Type | Taille | Classe Wrapper | --------- |--------------------------------|--------------------------------- | Boolean | | Boolean | char | 16 bits, Unicode | Character | byte | 8 bits | Byte | short | 16 bits | Short | int | 32 bits | Integer | long | 64 bits | Long | float | 32 bits IEEE 754 | Float | double | 64 bits IEEE 754 | Double | void | | Void |
  • 29. On peut traiter les type primitif comme des objet en utilisant les classe wrapper qui leurs sont associées. Exemple: char c=‘x’; // type primitif directement déclaré Character car = new Character (c); // classe wrapper ou Character car = new Character (‘x’);
  • 30. Remarque : Quand une donnée d’un type primitif est membre d’une classe on est assuré qu’elle a une valeur par défaut même si on ne l’initialise pas: ---------------------------------------------------------------- Type primitifs | Valeur par défaut | ---------------------------- | ----------------------------------- | boolean | false | char | ‘0000’ (null) | byte | (byte)0 | short | (short)0 | int | 0 | long | 0L | float | 0.0f | double | 0.0d | -----------------------------------------------------------------
  • 31. Attention: Cette garanti d’initialisation par défaut ne s’applique pas aux variables locales (définition d’une fonction (méthode)).
  • 32. V. Notion de portée et de durée de vie des objets Le concept de portée fixe simultanément la visibilité et la durée de vie des noms définis dans cette portée. La portée est fixée par les accolades { } . Exemple: { int x=12; // seul x est accessible { int q=96; // x et q tous les deux sont accessibles } // seul x est accessible // q est hors de portée }
  • 33. Attention: Ceci n’est pas permis en Java { int x=12; { int x=96; // illégale en Java, valable en C, C++ } }
  • 34. Portée des objet: Considérons une classe nommée A { A a= new A(); } // fin de portée La référence a disparaît à la fin de la portée, par contre l’objet qui été référencé par a existe toujours, mais on n’a aucun contrôle sur lui (il reste inaccessible). Les objets n’ont pas la même durée de vie que les types primitifs.
  • 35. Il n’existe aucun opérateur explicite pour détruire l’objet dont on n’a pas besoin, mais il existe un mécanisme de gestion automatique de la mémoire connu sous le nom de ramasse miettes (en anglais Garbage Collector). Son principe est le suivant: A tout instant on connaît le nombre de références à un objet donné. Lorsqu’il n’existe plus aucune référence sur un objet, on est certains que le programme ne peut pas y accéder, donc l’objet devient candidat au ramasse miette.
  • 36. VI. Champs de classe Considérons la définition simpliste suivante: class A { int n; float y; } Chaque objet de type A possède ses propres champs n et x. Par exemple avec les déclarations A a1= new A (), a2= new A (); a1.n et a2.n désignent deux champs différents. a1.y et a2.y désignent aussi deux champs différents.
  • 37. On peut définir des champs qui n’existent qu’en un seul exemplaire (ce qu’on nomme des champs de classe ou champs statiques), en les déclarant avec l’attribut static . Par exemple si nous définissons: class A { static int n; float y; } A a1= new A (), a2= new A (); a1.n et a2.n désignent donc le même champs. Il est possible de s’y référer en le nommant simplement A .n // champs (statique) de la classe A
  • 38. VII. Quelques précisions Identificateur: C’est une suite de caractères pour désigner les différentes entités manipulés par un programme: variables, méthode, classe, objet, … Il est formé de lettre et/ou de chiffres. Le premier caractère est une lettre ou le caractère souligné (_). Remarque: Tous les caractères sont significatifs. On fait la différence entre les majuscules et les minuscules. Mots clés: certains mots sont réservés par le langage et ne peuvent pas être utilisés comme identificateur.
  • 39. Mise en page des programmes La mise en page d’un programme Java est libre. Une instruction peut être étendue sur plusieurs lignes. Une ligne peut comporter plusieurs instructions Emploi du code Unicode: Java utilise le codage Unicode, qui est basé sur 2 octets (16 bits), par conséquent on peut coder 65 536 symboles, ce qui permet de couvrir la plus part des symboles utilisés dans le monde. Pour assurer la portabilité, le compilateur commence par traduire le fichier source en Unicode. On peut, par exemple, utiliser l’identificateur élément: int élément; On peut aussi utiliser le code Unicode d’un caractère (mais à éviter pour la lisibilité) de la manière suivante: xxxx représente le caractère ayant comme code Unicode la valeur xxxx. Par exemple 0041 représente le caractère A.
  • 40. Style de programmation non standard Mettre en Majuscule la première lettre des noms des classes. Exemple: class A () { //… } Si le nom de la classe est composée de plusieurs mots, ils sont accolés (on ne les sépare pas par un trait bas) et la première lettre de chaque mot est mise en majuscule. Exemple: class PremProg() { //…. } - Pour le reste, méthodes, variables membres, noms des références d’objets, le style retenu comme classe sauf que la première lettre de l’identificateur est miniscule.
  • 41. Spécificateurs d’accès: Il existe 3 mots clés pour spécifier l’accès au sein d’une classe: public , private et protected . public : veut dire tout le monde private : veut dire que personne ne peut accéder à ces définitions à part les méthodes interne de ce type. protected : se comporte comme private avec moins de restriction. Une classe dérivée a un accès aux membres protected mais pas aux membres private Accès par défaut, lorsqu’aucun de ces spécificateurs n’est mentionné.
  • 42. Exemple: class A { public int x; private int y; public void initialise (int i, int j){ x=i; y=j; } } public class TestA{ // fichier source de nom TestA.java public static void main (String args[]) { A a; a= new A(); // On peut aussi déclarer A a= new A(); a.initialise(1,3); // x vaut 1 et y vaut 3 a.x=2; // x vaut maintenant 2. On peut accéder à x car il est public a.y=3; // ne compile pas car y est privée } }
  • 43. Ch. II. Les constructeurs I . Introduction Un objet a – une adresse en mémoire (identifie l’objet) – un comportement (ou interface) – un état interne (les valeurs des variables) L’état interne est donné par des valeurs de variables Le comportement est donné par des fonctions ou procédures, appelées méthodes
  • 44. Nous supposons qu’un objet de type Point est représenté par: Un état interne : deux coordonnées entières l’abscisse (x) et l’ordonnée (y). Un Comportement: nous supposons que la classe dispose des trois méthodes: initialise pour attribuer des valeurs aux coordonnées d’un points déplace pour modifier les coordonnées d’un point affiche pour afficher les coordonnées d’un point
  • 45. public class Point{ private int x; // abscisse private int y; // ordonnée public void initialise (int abs,int ord){ x=abs; y=ord; } public void deplace (int dx, int dy){ x+=dx; y+=dy; } public void affiche (){ System.out.println( &quot; abscisse : &quot;+ x + &quot; ordonnée : &quot; + y ); } }
  • 46. Pour manipuler un objet, on déclare une référence sur la classe de cet objet : Exemple: Point a; Pour créer un objet ( instance de la classe ), on applique l'opérateur new. Exemple: a = new Point(); Quand une instance est créée, - son état est conservé dans les variables d’instance (son propre état interne) - partage le code qui détermine son comportement (les méthodes) avec les autres instances de la classe.
  • 47. Ainsi a= new Point(); // créer un objet de type Point et place sa référence dans a. Les objets interagissent en s’envoyant des messages: Les méthodes d’un objet correspondent aux messages qu’on peut lui envoyer : quand un objet reçoit un message, il exécute la méthode correspondante. De manière générale on a: objetQuiReçoitLeMessage.messageEnvoyé(paramètres); Exemple des objets de type point: a.initialise(1,1); a.deplace(0,2);
  • 48. public class TstPoint{ public static void main (String args[]) { Point a; a= new Point(); a.initialise(1,1); a.deplace(2,0); Point b= new Point(); b.initialise(2,3); b.affiche(); } }
  • 49. Remarque: Pour chaque instance on appelle la méthode initialise pour initialiser l’objet ainsi créer. Si on n’appelle pas la méthode initialise, l’objet de type Point ainsi créer ne sera pas initialisé.  Créer un objet, ne garanti pas son initialisation
  • 50. II. Définitions de Constructeur On peut garantir l’initialisation d’un objet grâce à une méthode spéciale appelée constructeur qui permet d’automatiser le mécanisme d’initialisation d’un objet. Quand une classe possède un constructeur, Java l’appel automatiquement à toute création d’objet avant qu’il ne puisse être utilisé. La création et l’initialisation sont deux concepts unifiés
  • 51. Chaque classe a un ou plusieurs constructeurs qui servent à créer les instances initialiser l’état de ces instances Un constructeur est une méthode qui: porte le même nom que la classe n’a pas de type retour peut disposer d’un nombre quelconque d’arguments (éventuellement aucun). Exemple: Prenons l’exemple de la classe point et transformons la méthode initialise en un constructeur en la nommant Point.
  • 52. public class Point{ private int x; // abscisse private int y; // ordonnée public Point (int abs, int ord) { // Constructeur, remplace initialise x=abs; y=ord; } public void deplace (int dx, int dy){ x+=dx; y+=dy; } public void affiche (){ System.out.println( &quot; abscisse : &quot;+ x + &quot; ordonnée : &quot; + y ); } }
  • 53. Les instructions: Point a= new Point(); a.initialise(1,1) Sont remplacées par Point a = new Point(1,1); // crée l’instance et l’initialise On peut aussi écrire: Point a; a= new Point(1,1); Attention. Dans la dernière version de la définition de la classe Point, l’instruction Point a = new Point(); ne convient plus car le constructeur a besoin de deux arguments
  • 54. Un autre exemple public class Etudiant { private String nom, prenom; // Variables d’instance private int codeNatEtudiant; // Constructeur public Etudiant(String n, String p) { nom = n; prenom = p; } public void setCNE (int cne) { codeNatEtudiant = cne; } public static void main(String[] args) { Etudiant e1; e1 = new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;); // création d'une instance de la classe Etudiant e1.setCNE(23456765); } }
  • 55. III. Quelques règles concernant les constructeurs 1. Aucun type, même void, ne doit figurer devant son nom. 2. Lorsque le code d’une classe ne comporte pas de constructeur, un constructeur par défaut sera automatiquement ajouté par Java. Dans ce cas on peut créer des instances (objets) de la classe par des instructions telles que: Point a= new Point(); // ok si Point n’a pas de constructeur Etudiant e= new Etudiant(); // ok si Etudiant n’a pas de constructeur
  • 56. De manière générale: Si pour une classe A donnée, l’instruction suivante est acceptée A a= new A(); Cela signifie que: Soit A ne possède pas de constructeur Soit A possède un constructeur sans arguments.
  • 57. 3. Un constructeur ne peut pas être appelé de la même manière que les autres méthodes. Par exemple: Point a= new Point(1,1); // ok car Point possède un constructeur e1.Etudiant((&quot;Mohammed&quot;, &quot;Ali&quot;); // Interdit car Etudiant possède // un constructeur. 4. Un constructeur peut être déclaré private . Dans ce cas il ne pourra plus être appelé de l’extérieur, c’est-à-dire il ne pourra pas être utiliser pour instancier des objet. Exemple: class A{ private A() { … } // constructeur privée sans arguments … } … A a=new A(); // erreur, le constructeur correspondant A() est privé
  • 58. Dans les exemples précédents, le constructeur initialise les champs privés de l’objet. Remarque: les champs d’un objet sont toujours initialisés par défaut, contrairement à ce qui se passe pour les variables locales, . La création d’un objet entraîne toujours, par ordre chronologique, les opérations suivantes: Initialisation par défaut de tous les champs de l’objet Une initialisation explicite lors de la déclaration du champ L’exécution des instructions du corps du constructeur
  • 59. Initialisation par défaut des champs d’un objet : ------------------------------------ |--------------------------------- Type du champ | Valeur par défaut ------------------------------------ |-------------------------------- boolean | false char | caractère de code nul int, byte, short, int long | 0 float , double | 0.f ou 0. class | null ---------------------------------------------------------------------
  • 60. Initialisation explicite des champs d’un objet : Une variable locale peut être initialiser lors de sa déclaration. Il en va de même pour un champs. Considérons: class A{ public A (…) {… } // Constructeur A … private int n=10; private int p; }
  • 61. L’instruction suivante A objA = new A(…); Entraîne successivement l’initialisation implicite des champs n et p de l’objet objA à 0 L’initialisation (explicite) du champ n à la valeur figurant dans sa déclaration, soit 10 L’exécution des instruction du constructeur
  • 62. Appel du constructeur Le corps du constructeur n’est exécuté qu’après l’initialisation par défaut et l’initialisation explicite.
  • 63. class A { public A() { // ici n vaut 20, p vaut 10 et np vaut 0 np=n*p; n=5; } public void affiche(){ System.out.println ( &quot; n= &quot; +n+&quot; p= &quot; +p+ &quot; np= &quot; + np) } private int n=20, p=10; private int np; } public class Init { public static void main (String args[]) { A a= new A() ; // ici a.n vaut 5, a.p vaut 10, mais a.np vaut 200 a.affiche(); } } Résultat de l’appel de la méthode affiche: n=5 p=10 np = 200
  • 64. IV. Surcharge des méthodes On parle de surcharge (en anglais overload) lorsqu’un même symbole possède plusieurs significations différentes entre lesquelles on choisit en fonction du contexte. Par exemple a+b, la signification du symbole + dépend du type des variables a et b. En Java et C++, on peut surcharger une méthode , c’est-à-dire, ajouter une méthode qui a le même nom mais pas la même signature qu’une autre méthode :
  • 65. Considérons l’exemple suivant ou la classe Etudiant est dotée de 2 méthodes calcMoyenne: La première a deux arguments de ype float La deuxième a quatre arguments de type float
  • 66. class Etudiant { private String nom, prenom; // Variables d’instance private int codeNatEtudiant; // Constructeur public Etudiant(String n, String p) { nom = n; prenom = p; } public void setCNE (int cne) { codeNatEtudiant = cne; } public float calcMoyenne(float m1, float m2) { return (m1+m2)/2; } public float calcMoyenne(float m1, float m2, float m3, float m4) { return (m1+m2+m3+m4)/4; } }
  • 67. public class TestEtudiant { public static void main(String[] args) { Etudiant e1; e1 = new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;); // e1.setCNE(23456765); System.out.println ( “Moy1 = &quot; +e1.calcMoyenne(10, 12)); System.out.println ( “Moy2 = &quot; +e1.calcMoyenne(10, 12, 8, 13)); } }
  • 68. Considérons maintenant l’exemple suivant ou la classe Point est dotée de 3 méthodes déplace: La première a deux arguments de type int La deuxième a un seul argument de type int La troisième a un seul argument de type short
  • 69. class Point { public Point (int abs, int ord){ // Constructeur x=abs; y=ord; } pubic void deplace (int dx, int dy) { x+=dx; y+=dy; } pubic void deplace (int dx) { x+=dx; } pubic void deplace (short dx) { x+=dx; } private int x,y; }
  • 70. public class Surdef1 { public static void main (String arg[]) { Point a=new Point(1,2); a.deplace(1,3); // appel deplace (int,int) a.deplace(2); // appel deplace (int) short p=3; a.deplace(p); // appel deplace (short) byte b=2; a.deplace(b); /* appel deplace(short) après conversion de b en short */ } }
  • 71. Il peut y avoir ambiguïté Supposons que la classe Point est dotée des deux méthodes deplace suivantes: public void deplace(int dx, byte dy) { x+=dx; y+=dy; } public void deplace(byte dx, int dy) { x+=dx; } Considérons alors les instructions suivantes: Point a = new Point(2,4) int n; byte b; a.deplace(n,b); // ok appel de deplace (int,byte) a.deplace(b,n); // ok appel de deplace (byte,n) a.deplace(b,b); // erreur, ambiguité
  • 72. En Java, il est interdit de surcharger une méthode en changeant le type de retour uniquement: c’est-à-dire ne différencier les 2 méthodes que par leur type retour Par exemple, one peut pas avoir les 2 méthodes suivante dans une classe : int moyenne(int, int); // division entière par 2 float moyenne(int,int); // moyenne réelle
  • 73. Surcharge des constructeurs (Plusieurs constructeurs) En Java et C++, une classe peut avoir plusieurs constructeurs. Comme le nom du constructeur est identique du nom de la classe, il ne peut y avoir qu’un seul nom de constructeur. Par contre on peut avoir différentes initialisations. class Etudiant { private String nom, prenom; // Variables d’instance private int codeNatEtudiant; public Etudiant(String n, String p) { // Constructeur nom = n; prenom = p; } public Etudiant(String n, String p, int cne) {// Constructeur nom = n; prenom = p; codeNatEtudiant = cne; } }
  • 74. public class TestEtudiant { public static void main(String[] args) { Etudiant e1, e2; e1 = new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;); e2 = new Etudiant(&quot;Ouardi&quot;, &quot; fatima&quot;, 22564321); } }
  • 75. V. Autoréférences: emploi de this Il se peut qu’au seine d’une méthode, on ait besoin de faire référence à l’objet ayant appelé cette méthode. class A { … . public void f(….) { …… // ici l’emploi de this désigne la référence à l’objet // ayant appelé la méthode f } }
  • 76. Exemple 1: class Point { public Point (int abs, int ord){ x=abs; y=ord; } … private int x, y; } Comme les identificateurs abs et ord sont des arguments muets pour la méthode Point, alors on peut les noter x et y qui n’ont rien avoir avec les champs private x et y. Dans ce cas la classe Point peut s’écrire comme suit:
  • 77. class Point { public Point (int x, int y){ this .x=x; // this .x permet d’accéder au champs x de l’objet courant this .y=y; // this .y permet d’accéder au champs y de l’objet courant } … private int x,y; }
  • 78. Exemple 2: class Etudiant { private String nom, prenom; public Etudiant(String nom, String prenom) { this.nom = nom; this.prenom = prenom; } }
  • 79. Exemple 3: Deux objets de même classe Point coïncident si leurs coordonnées sont identiques. On peut écrire la méthode coïncide de la façon suivante: pubic boolean coincide (Point pt) { return ((pt.x== this .x) && (pt.y== this .y)) } Point a= new Point(x1,y1); Point b= new Point(x2,y2); Les point a est b sont identiques si: a.coincide(b) est TRUE
  • 80. Utilisation du mot clé this dans un constructeurs Il est possible, qu’au sein d’un constructeur, on peut appeler un autre constructeur de la même classe. Pour faire on fait appel au mot clé this qui est utilisé cette fois comme nom de méthode. Supposons que la classe Point admet deux constructeurs. Un constructeur initialise à l’origine (au point (0,0)) et un autre initialise à un point quelconque.
  • 81. Version 1: La classe Point peut être définie de la façon suivante: class Point { public Point ( int abs, int ord){ x=abs; y=ord; } public Point( ) { x=0; y=0; } … private int x,y; } Point a = new Point (); // créer l’objet a et l’initialise à l’origine, // au point (0,0). Point b = new Point (2,3); // créer l’objet b et l’initialise au poi nt (2,3).
  • 82. Version 2: la classe Point peut être définie de la façon suivante: class Point { public Point ( int abs, int ord){ x=abs; y=ord; } public Point( ) { this (0,0); } … private int x,y; } Point a = new Point (); // créer l’objet a et l’initialise à l’origine, // au point (0,0). Point b = new Point (2,3); // créer l’objet b et l’initialise au point (2,3).
  • 83. public class feuille { int i=0; feuille increment () { i++; return this; } public static void main (String[] args ) { feuille x=new feuille (); System.out.println(&quot;ii = &quot; + x.increment().increment().increment().i ); } } Sortie: i= 3
  • 84. public class feuille { int i=0; feuille increment () { i++; return this; } void print () { System.out.println (&quot; i = &quot; + i); } public static void main (String[] args ) { feuille x=new feuille (); x.increment().increment().increment().print( ) } } Sortie: i= 3
  • 85. Ch. III. Généralités sur les structures lexicales de Java Types de variables Les variables d’instances sont déclarées en dehors de toute méthode conservent l’état d’un objet, instance de la classe sont accessibles et partagées par toutes les méthodes de la classe Les variables locales sont déclarées à l’intérieur d’une méthode conservent une valeur utilisée pendant l’exécution de la méthode ne sont accessibles que dans le bloc dans lequel elles ont été déclarées
  • 86. Identificateurs Un identificateur Java est une chaîne de caractères de longueur quelconque: Le premier caractère est une lettre Unicode Le reste de la chaîne peut contenir des lettres et/ou des chiffres et/ou le caractère souligné « _ » Les minuscules et les majuscules sont différenciés Un identificateur Java ne doit pas être un mot-clé ou les constantes true , false ou null
  • 87. L’affectation L’affectation est réalisée au moyen de l’opérateur « = ». Signifie prendre la valeur du coté droit et la copier du coté gauche.  La partie droite est une constante, une variable ou une expression qui retourne une valeur. La partie gauche est une variable . variable = constante ou variable ou expression
  • 88. Soient A et B de type primitif A=B; signifie que le contenu de B est copié dans A. Si ensuite on modifie le contenu de A, alors le contenu de B ne sera pas modifié. Soient A est B deux objets, A=B; signifie qu’on copie la référence de B dans A. (A et B pointeront vers le même objet référencé par B). Si ensuite le contenu de A ou de B sont modifiés alors le contenu de A et de B sont modifiés.
  • 89. Exemple: class A { public int i; } public class TestAffectation { public static void main(String[] args) { A a=new A(); A b=new A(); a.i=6; b.i=11; a=b; // a et b contiennent la même référence, on a: a.i=11 a.i=20; // b.i et a.i valent 20 b.i=13; // a.i et b.i valent 13. } }
  • 90. Types de données en Java 2 grands groupes de types de données sont manipulés par Java: types primitifs objets (instances de classe)
  • 91. Types primitifs Boolean: prend deux valeurs true ou false Nombres entiers : byte: représenté sur 1 octet, short: représenté sur 2 octets, int : représenté sur 4 octets, long : représenté sur 8 octets Nombres à virgule flottante : float : représenté sur 4 octets), double : représenté sur 8 octets Caractère (un seul caractère) : char : codé sur 2 octet par le codage Unicode
  • 92. Nombres entiers byte : compris entre –128 et 127 short : compris entre –32 768 et 32 767 int : compris entre –2.147 483 648 et 2 147 483 647 long : compris entre -923 372 036 854 775 808 et 923 372 036 854 775 807
  • 93. Constantes nombres Une constante « entière » est de type int Si elle est suffixée par « L » alors elle est de type long Exemple: 108 // constante de type int 89L // constante de type long 014 // 14 en octal (base 8)= 12 en décimal 0xA7 // A7 en hexadécimal (base 16) = 167 en décimal
  • 94. Types des résultats des calculs avec des nombres entiers Tout calcul entre entiers donne un résultat de type int si au moins un des opérandes est de type long , alors le r ésultat est de type long Exemple byte b1 = (byte)20; byte b2 = (byte)15; byte b3 = b1 + b2; provoquera une erreur car b1 + b2 est de type int (codé sur 32 bits) alors que b3 est de type byte (codé sur 8 bits seulement)
  • 95. Les nombres flottants float : environ 7 chiffres significatifs ; valeur absolue (arrondie) maximal 3,4 x 10 38 ( constante prédéfinie Float.MAX_VALUE ) valeur absolue (arrondie) minimal 1,4 x 10 -45 (constante prédéfinie Float.MIN_VALUE ) double : environ 15 chiffres significatifs ; valeur absolue maximal (arrondie) 1,8 x 10 308 (constante prédéfinie Double.MAX_VALUE ) valeur absolue minimal (arrondie) 4,9 x 10 -324 (constante prédéfinie Double.MIN_VALUE )
  • 96. Constantes nombres Une constante réelle est de type float si elle est suffixée par « F » et de type double sinon Exemple: .567e2 // 5,67 de type double 5.123E-2F // 0,05123 type float
  • 97. Type caractère permet de manipuler des caractères: Java représente un caractère sur 2 octets Une variable de type caractère est déclaré par: char c1,c2; Constante de type caractère: ‘a’ , ‘E’ Les caractères disposant d’une notation spéciale. Notation Code Unicode Abréviation usuelle Signification amp;quot; 0008 0009 000a 000c 000d 0022 0027 005c BS(Back Space) HT(Horizontal Tabulation) LF(Line Feed) FF(Form Feed) CR(Cariage Return) Retour arrière Tabulation horizontale Saut de ligne Saut de page Retour chariot
  • 98. Type booléen Sert à représenter une valeur logique du type vrai/faux Une variable de type booléen est déclaré par: boolean b; b prend une des deux valeurs false ou true
  • 99. Constante null Référence inexistante (indique qu’une variable de type non primitif ne référence rien) ; convient pour tous les types non primitifs null
  • 100. Transtypage Java est un langage fortement typé Dans certains cas, il est nécessaire de forcer le programme à considérer une expression comme étant d’un type qui n’est pas son type réel ou déclaré On utilise pour cela le cast (transtypage) : ( type-forcé ) expression int x = 10, y = 3; double z; z=x/y; // donne z=3.0; car x/y donne 3 // sin on veut que z=3.3333.. et pas 3.0 z = (double)x / y; // cast de x suffit
  • 101. Casts autorisés En Java, 2 seuls cas sont autorisés pour les casts : entre types primitifs, entre classes mère/ancêtre et classes filles.
  • 102. Casts entre types primitifs Un cast entre types primitifs peut occasionner une perte de données : conversion d'un int vers un short Un cast peut provoquer une simple perte de précision: la conversion d'un long vers un float peut faire perdre des chiffres significatifs mais pas l'ordre de grandeur
  • 103. Casts entre types primitifs Une affectation entre types primitifs peut utiliser un cast implicite si elle ne provoque aucune perte De même, on peut affecter un entier à une variable de type nombre à virgule flottante Sinon, elle doivent comporter un cast explicite L’oubli de ce cast explicite provoque une erreur à la compilation
  • 104. Exemples de Casts short s = 1000000; // erreur ! Cas particulier d’une affectation statique (repérable par le compilateur) d’un int « petit » : short s = 65; // pas d’erreur Pour une affectation non statique, le cast est obligatoire : int i = 60; short b = (short)(i + 5); Les casts de types « flottants » vers les types entiers tronquent les nombres : int i = (int)1.99; // i = 1, et pas 2
  • 105. Casts entre entiers et caractères Ils font correspondre un entier et un caractère qui a comme code Unicode la valeur de l’entier La correspondance char -> int , long s’obtient par cast implicite Le code d’un char peut aller de 0 à 65.535 donc char -> short , byte nécessite un cast explicite ( short ne va que jusqu’à 32.767) Les entiers sont signés et pas les char donc long , int , short ou byte -> char nécessite un cast explicite
  • 106. L’attribut final L’attribut final indique que la valeur de la variable ne peut être modifiée : on pourra lui donner une valeur une seule fois dans le programme. Variable d’instance final Une variable d’instance final est constante pour chaque objet. Attention: elle peut avoir 2 valeurs différentes pour 2 objets différents. Une variable d'instance final peut ne pas être initialisée à sa déclaration mais elle doit avoir une valeur à la sortie de tous les constructeurs
  • 107. Variable locale final Si la variable est d’un type primitif, sa valeur ne peut changer Si la variable référence un objet, elle ne pourra référencer un autre objet mais l’état de l’objet pourra être modifié final Etudiant e = new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;); . . . e.nom = &quot;Ahmed&quot;; // ok, changement de l’état e l’objet e.setCNE(32211452); // ok, changement de l’état e l’objet e = new Etudiant(&quot;Ahmed&quot;); // Interdit , référence à un // autre objet
  • 109. Structure Alternative « if… else » if ( expressionBooléenne ) bloc-instructions ou instruction else bloc-instructions ou instruction int x = y + 5; if (x % 2 == 0) { type = 0; x++; } else type = 1; Un bloc serait préférable, même s’il n’y a qu’une seule instruction
  • 110. Expression conditionnelle expressionBooléenne ? expression1 : expression2 Est équivalent if ( expressionBooléenne) expression1; else expression2; Exemple: int y = (x % 2 == 0) ? x + 1 : x; est équivalent à int y; if (x % 2 == 0) y = x + 1; else y = x; Parenthèses pas indispensables
  • 111. Distinction de cas suivant une valeur switch( expression ) { case val1 : instructions ; break; // Attention, sans break , les instructions du cas suivant // sont exécutées ! ... case valn : instructions ; break; default: instructions ; } expression est de type char , byte , short , ou int , ou de type énumération S’il n’y a pas de clause default , rien n’est exécuté si expression ne correspond à aucun case
  • 112. Exemple de switch char lettre; int nbVoyelles = 0, nbA = 0, nbT = 0, nbAutre = 0; . . . switch (lettre) { case 'a' : nbA++; case 'e' : // pas d’instruction ! case 'i' : nbVoyelles++; break; case 't' : nbT++; break; default : nbAutre++; }
  • 113. Répétitions « tant que » while( expressionBooléenne ) bloc-instructions ou instruction do bloc-instructions ou instruction while( expressionBooléenne ) Le bloc d’instructions est exécuté au moins une fois
  • 114. Répétition for for( init ; test ; incrément ){ instructions ; } est équivalent à init ; while ( test ) { instructions ; incrément }
  • 115. Exemple de for int somme = 0; for (int i=0; i < n; i++) { somme += tab[i]; } System.out.println(somme);
  • 116. Instructions liées aux boucles break sort de la boucle et continue après la boucle continue passe à l’itération suivante break et continue peuvent être suivis d’un nom d’étiquette qui désigne une boucle englobant la boucle où elles se trouvent (une étiquette ne peut se trouver que devant une boucle)
  • 117. Etiquette de boucles boucleWhile: while (pasFini) { ... for (int i=0; i < n; i++) { ... if (t[i] < 0) continue boucleWhile; ... } ... }
  • 118. Les tableaux En Java les tableaux sont considérés comme des objets. – les variables de type tableau contiennent des références aux tableaux – les tableaux sont créés par l’opérateur new – ils ont une variable d’instance ( final ) pour désigner taille du tableau: final int length
  • 119. Déclaration et création des tableaux Déclaration : La taille n’est pas fixée à la déclaration int[] tabNotes; Ou int tabNotes[]; // possible, mais non recommandé Attention: En java il n'est pas possible de définir des tableaux de taille statique à la déclaration. int[10] tab; // ne compile pas Création : C’est pendant la création qu’il faut donner la taille du tableau tabNotes = new int[5]; Remarques: Chaque élément du tableau reçoit la valeur par défaut du type de base du tableau La taille ne pourra plus être modifiée par la suite Les éléments d’un tableau peuvent être d’un type primitif ou d’un type objet
  • 120. Initialisation On peut lier la déclaration, la création et l’initialisation d’un tableau; Sa longueur est alors calculée automatiquement d’après le nombre de valeurs données. Attention : cette syntaxe n'est autorisée que dans la déclaration) : int[] tab = {10, 3*6, 4}; Etudiant [] etudiantsSMI = { new Etudiant(&quot;Mohammed&quot;, &quot;Ali&quot;), new Etudiant( &quot; Fatima&quot;, &quot; Zahra&quot;) } On peut affecter « en bloc » tous les éléments d'un tableau avec un tableau anonyme int[] t; t = new int[] {1, 2, 3};
  • 121. Indices du tableau: Les indices du tableau commence à 0 et se termine à tab.length - 1 Taille du tableau int[] tab = {10, 3*6, 4}; tabNotes = new int[8]; int l1 = tab.length; // l1 = 3 int l2 = tabNots.length; // l2 = 8 int e = tabNotes[8]; /* La compilation produit le message suivant : ArrayIndexOutOfBoundsException */
  • 122. Exemple de tableau de chaînes: Paramètres de la ligne de commande class TestArguments { public static void main(String[] args) { for (int i=0; i < args.length; i++) System.out.println(args[i]); } } $javac TestArguments $ java TestArguments arg1 arg2 affichera arg1 arg2
  • 123. Tableaux d’objets Les éléments d’un tableau peuvent être d’un type objet. Attention: Il faut créer les objets avant de les utiliser. Considérons l’exemple de la classe Etudiant. Etudiants [] etudiantSMI = new Etudiant[100]; // Chaque élément du tableau contient une référence vers un objet de type Etudiant etudiantSMI[0].setCNE(11225467); // setCNE(int cne) est une méthode de la classe Etudiant . etudianSMI[0].codeNatEtudiant = cne; // Erreur: etudiantSMI[0] est objet de type Etudiant, donc il faut le créer avant de l’utiliser Etudiant [] etudiantSMI = new Etudiant[100]; // Chaque élément du tableau est une référence à un objet de type Etudiant etudiantSMI[0] = new Etudiant(); // Création de l’objet etudiantSMI[0] etudiantSMI[0].setCNE(11225467);
  • 124. Affectation de Tableaux : Java permet de manipuler globalement les tableaux par affectation de leurs références Soient t1 et t2 deux tableaux t1=t2; // La référence contenue dans t2 est affectée à t1 Maintenant t1 et t2 désignent le même objet tableau qui était initialement référencé par t2 t1[2]=3; // t2[2] vaut aussi 3 t2[2]=3. t2[4]=6; // t1[4] vaut aussi 6 t1[4]=6; Attention: Si on veut copier uniquement les valeurs de t2 dans t1, alors dans ce cas on peut faire une copie élément par élément
  • 125. Les tableaux en argument d’une méthode: Le passage des tableaux comme paramètres des méthodes se fait par référence (comme les objets) et non par copie (comme les types les types primitifs) La méthode agit directement sur le tableau et non sur sa copie
  • 126. Tableaux à plusieurs dimensions Déclaration int[][] notes; // c’est un tableau de tableaux Chaque élément du tableau contient une référence vers un tableau Création: Il faut donner au moins les premières dimensions notes = new int[30][3]; // Tableau de 30 étudiants, chacun // des 30 étudiants a au plus 3 notes notes = new int[30][]; // Chacun des 30 étudiants a un // nombre de notes variable
  • 127. Déclaration, création et initialisation int[][] notes = { {10, 11, 9}, // 3 notes {15, 8}, // 2 notes . . . }; Affectation notes[10][2] = 12;
  • 128. Exemple int[][] t; t = new int[2][]; int[] t0 = {0, 1}; t[0]= t0; // t[0] est un tableau t[1] = new int[] {2, 3, 4, 5}; // Déclaration et initialisation for (int i = 0; i < t.length; i++) { for (int j = 0; j < t[i][].length; j++) { System.out.print(t[i][j] + &quot;; &quot;); } System.out.println(); }
  • 129. Ch. IV. Héritage L'héritage est une notion fondamentale en Java et de manière générale dans les langages de programmation par Objets. Il permet de créer des classes dérivées (classes qui héritent) par combinaison de classes déjà existantes (classes de base) sans toucher au code source de la classe de base (on a seulement besoin du code compilé de la classe de base).
  • 130. La classe dérivée: se comporte comme la classe de base mais avec quelques différences. on a seulement besoin du code compilé de la clase de base. On peut par exemple: – ajouter de nouvelles méthodes – adapter (modifier) certaines méthodes
  • 131. Syntaxe: class <ClasseDerivee> extends <ClasseDeBase> Interprétation: Permet de définir un lien d'héritage entre deux classes: La classe <ClasseDeBase> est le nom de la classe de base. Elle s'appelle une classe mère , une classe parente ou une super-classe . Le mot clef extends indique la classe mère : La classe <ClasseDerivee> est le nom de la classe dérivée. Elle hérite de la classe < ClasseDeBase > . On l'appelle une classe fille ou une sous-classe Remarque: Par défaut il n’y a pas de extends dans la définition d’une classe: une classe hérite de la classe Object Un objet de la classe dérivée ClassDerivee accède aux membres publics de sa classe de base ClasseDeBase
  • 132. Exemple class FormeGeometrique{ // classe mère // Définition des attributs et des méthodes } class Point extends FormeGeometrique { // classe dérivée // Définition de nouveaux attributs (propres à la classe Point) // Définition de nouvelles méthodes (propres à la classe Point) // Modification des méthodes qui sont déjà définies dans la classe mère // Point hérite des méthodes et attributs de la superclasse FormeGeometrique } class Cercle extends Point { Définition de nouveaux attributs (propres à la classe Cercle) // Définition de nouvelles méthodes (propres à la classe Cercle) // Modification des méthodes qui sont déjà définies dans la classe mère // Cercle hérite des méthodes et attributs de la superclasse Point }
  • 133. Une instance (un objet) d’une classe dérivée peut faire appelle (accès depuis l’extérieur) Aux méthodes et aux membres publics de la classe dérivée Aux méthodes et membres publics de la classe de base De même (pour l’accès depuis l’intérieur) Une méthode d’une classe dérivée a accès aux membres publics de sa classe de base Une méthode d’une classe dérivée n’a pas accès aux membres privées de sa classe de base
  • 134. Quand on écrit la classe <ClasseDerivee> on doit seulement: écrire le code (variables ou méthodes) lié aux nouvelles possibilités: offrir de nouveaux services. redéfinir certaines méthodes: enrichir les services rendus par une classe.
  • 135. Lorsqu'une classe hérite d'une autre classe Elle bénéficie automatiquement des définitions des attributs et des méthodes de la classe mère. Elle peut y ajouter ses propres définitions. ajouter des variables, des méthodes et des constructeurs. redéfinir des méthodes: exactement le même nom et la même signature. surcharger des méthodes: même nom mais pas les mêmes arguments (signature).
  • 136. Remarques2: Java ne permet pas l’héritage multiple: chaque classe a une et une seule classe mère dont elle hérite les variables et les méthodes. C++ permet l’héritage multiple.
  • 137. Construction des classes dérivée Lorsqu'on construit une instance de ClasseDerivee , on obtient un objet dont une partie est construite grâce à la définition de ClasseDerivee et une partie grâce à la définition de la super­classe ClasseDeBase . - En Java, le constructeur de la classe drivée doit prendre en charge l’intégralité de la construction de l’objet.  Le constructeur de la classe dérivée doit faire appel au constructeur de la classe de base en appelant explicitement la méthode super() ainsi que la liste des paramètres appropriés. Remarque: l’appel du constructeur de la super classe (appel de la méthode super()) doit être la première instruction dans la définition du constructeur de la classe dérivée.
  • 138. Exemple 1: class ClasseDeBase{ public ClasseDeBase(int i) { // constructeur de la classe de base System.out.println (&quot; Classe de Base: &quot; + i); } } class ClasseDerivee1 extends ClasseDeBase { public ClasseDerivee1(int i, int j) { // constructeur de la classe dérivée 1 super(i+j); // appel du constructeur ClasseDeBase System.out.println (&quot; Classe dérivée1: &quot; + i+ &quot; , &quot;+j); } } class ClasseDerivee2 extends ClasseDerivee1{ public ClasseDerivee2(int i) { // constructeur de la classe dérivée 2 super(i,i); // appel du constructeur ClasseDerivee1 System.out.println(&quot; Classe dérivée2: &quot; + i); } }
  • 139. public class TestHeritage{ public static void main (String args[]) { ClasseDerivee2 a= new ClasseDerivee2(7); } } Sortie: Classe de Base : 14 Classe dérivée1: 7 , 7 Classe dérivée2: 7
  • 140. Exemples des cas possibles: Exemple 1: class ClasseDeBase{ ClasseDeBase(arguments) { … } … } class ClasseDerivee extends ClasseDeBase { // Pas de constructeur … . } On obtient une erreur de compilation. Un constructeur de la classe dérivée doit être défini est qui doit appeler le constructeur de la classe de base.
  • 141. Exemple2: class ClasseDeBase{ ClasseDeBase(arguments) { // constructeur de la classe de base … } } class ClasseDerivee extends ClasseDeBase { ClasseDerivee(arguments) { // constructeur de la classe de base // l’appel de super () est obligatoire sinon une erreur … . } }
  • 142. Exemple 3: class ClasseDeBase{ ClasseDeBase(arguments) { // constructeur de la classe de base … } ClasseDeBase() { // constructeur sans paramètre de la classe de base … } } class ClasseDerivee extends ClasseDeBase { ClasseDerivee(arguments) { // constructeur de la classe dérivée // l’appel de super () n’est pas obligatoire. // si super() n’est pas appelé explicitement, // le constructeur par défaut de ClasseDeBase est appelé … . } }
  • 143. Exemple 4: class ClasseDeBase{ // Pas de constructeur … } class ClasseDerivee extends ClasseDeBase { // Pas de constructeur … . } La création d’un objet de type ClasseDerivee entraîne l’appel de constructeur par défaut qui appelle le constructeur par défaut de la ClasseDeBase.
  • 144. Exemple pratique: class ClasseDeBase{ ClasseDeBase() { System.out.println(&quot; Classe de Base: &quot;); } } class ClasseDerivee1 extends ClasseDeBase { ClasseDerivee1() { // Appel implicite du constructeur par défaut de ClasseDeBase System.out.println(&quot; Classe dérivée1: &quot;); } } class ClasseDerivee2 extends ClasseDerivee1{ ClasseDerivee2() { // Appel implicite du constructeur par défaut de ClasseDerivee1 System.out.println(&quot; Classe dérivée2: &quot; ); } }
  • 145. public class TestHeritage{ public static void main (String args[]) { ClasseDerivee2 a=new ClasseDerivee2(); } } Sortie: Classe de Base : Classe dérivée1: Classe dérivée2:
  • 146. Résumé: Si on n'appelle pas le constructeur de la super­classe, le constructeur par défaut est utilisé si: aucun constructeur n’est défini au moins un constructeur sans paramètre est défini sinon le compilateur déclare une erreur
  • 147. Notion de la Redéfinition Ne pas confondre redéfinition et surcharge des méthodes : – on redéfinit une méthode quand une nouvelle méthode a le même nom et la même signature qu’une méthode héritée de la classe mère. – on surcharge une méthode quand une nouvelle méthode a le même nom, mais pas la même signature, qu’une autre méthode de la même classe
  • 148. ­ Lorsqu'un attribut ou une méthode ont été définis dans une classe et sont redéfinis dans une classe dérivée (qui en hérite), les éléments visibles sont ceux redéfinis dans la classe dérivée. Les éléments de la classe de base (héritée) sont alors masqués. class Rect extends ObjetGraphique { void move(int dx, int dy); ... } class Cercle extends ObjetGraphique{ void move(int dx, int dy); ... }
  • 149. ­ On peut avoir les mêmes méthodes move() dans des classes héritant les unes des autres. Dans ce cas, c'est la classe la plus dérivée de l'objet qui détermine la méthode à exécuter, sans que le programmeur ait à faire des tests sur le type de l'objet à traiter.
  • 150. C* F E D* B A* *: signifie la définition ou la redéfinition d’une méthode f. Class A: méthode de A Classe B: méthode de A Classe D: méthode de D Classe E: méthode de A Classe C: méthode de C Classe F: méthode de C
  • 151. ­ la redéfinition d'une méthode d'une classe consiste à fournir dans une sous­classe une nouvelle implémentation de la méthode. Cette nouvelle implémentation masque alors complètement celle de la super­classe ­ Grâce au mot­clé super, la méthode redéfinie dans la sous­classe peut réutiliser du code écrit dans la méthode de la super­classe, qui n'est plus visible autrement. ­ super à un sens uniquement dans une méthode (comme le mot­clé this).
  • 152. class Point { public void afficher(){ System.out.pritln (&quot; je suis en &quot;+ x +&quot; et &quot; +y); } private int x,y; } class PointCol extends Point { public void afficher() { // redéfinition de la méthode afficher super. afficher(); // appel de la méthode afficher de la classe de base System.out.println (&quot; et ma couleur est: &quot;+ couleur);   } private byte couleur; }
  • 153. Soit une classe B qui hérite d'une classe A. Soit f une méthode définie dans A. Dans une méthode d'instance g () de B , super. sert à désigner un membre de A. par exemple: super.f() désigne la méthode f() de A Attention: On ne peut remonter plus haut que la classe mère pour récupérer une méthode redéfinie : – pas de « super.super. »
  • 154. Exemple: class A { public void f(){ System.out.println(&quot;Je suis dans la classe de base A&quot;); } } class B extends A { public void g(){ super.f(); // désigne la méthode f() de la classe mère A System.out.println(&quot;je suis aussi dans la class derivee B&quot;); } } public class TestRedefinition { public static void main (String args[]) { B b = new B(); b.g(); } }
  • 155. Héritage (Suite) Une Classe final ne peut pas avoir de classes filles La redéfinition d'une méthode public ne peut être private Une méthode final ne peut pas être redéfinie
  • 156. Sous-type Le type B est un sous-type de A si on peut affecter une expression de type B dans une variable de type A. Les type primitifs int est un sous type de float float est un sous type de double … Les objets Les sous-classes d’une classe A sont des sous types de A. Dans ce cas on peut écrire: A a = new B(…); // la variable a est de type A, alors que // l’objet référencé par a est de type B. A aa; B b=new B(); aa=b; // aa de type A, référence un objet de type B
  • 157. Définitions: La classe (ou le type) réelle de l’objet est la classe du constructeur qui a créé l’objet Exemple: Soit B une sous classe de A A a = new B(…); // B est la classe (type) réelle de l’objet a Le type (la clase) déclaré de l’objet est le type qui est donné au moment de la déclaration de la variable qui référence l’objet. Exemple: Soit B une sous classe de A A a = new B(…); // A est le type déclaré de l’objet a
  • 158. Cas des tableaux Soit B une classe qui hérite de la classe A, alors on peut écrire : A[] tab = new B[5]; Attention: Dans tab[] il faut les valeurs de type réel et non celles du type déclaré (c’est à dire des valeur de type B et non de type A). Par exemple, si on a les instructions suivantes: A[] tab = new B[5]; A a = new A(); tab[0] = a; Passe à la compilation mais provoquera une erreur à l’exécution car tab[0] reçoit une valeur de type A et non une valeur de type B
  • 159. Polymorphisme Exemple introductif: Considérons l’exemple suivant où B est une classe qui hérite de la classe A. Soient f() une méthode qui reédinie dans B et g une méthode définie dans A. On suppose que class A { public void f(){ System.out.println(&quot;Methode f(): Classe de base A&quot;); } public void g(){ System.out.println(&quot;Methode g(): Classe de base A&quot;); } } class B extends A { public void f(){ System.out.println(&quot;Methode f(): Classe B derivee de A&quot;); public void h(){ System.out.println(&quot;Methode h(): Classe B derivee de A&quot;); } }
  • 160. A a=new A(); B b = new B(); a.f(); // appelle la méthode définie dans A a=b; // A a = new(B); a.f(); // appelle la méthode définie dans B a.g(); // appelle la méthode définie dans A b.g(); // appelle la méthode définie dans A Il faut noter que la même écriture a.f(); peut correspondre à des appels différents de la méthode f(). Ceci est réalisé grâce au polymorphisme. Le Polymorphisme veut dire que le même service peut avoir un comportement différent suivant la classe dans laquelle il est utilisé. C’est un concept fondamental de la programmation objet, indispensable pour une utilisation efficace de l’héritage
  • 161. Attention c’est important: Si on a: B b = new B(); b.h(); // appelle la méthode h() définie dans B A a=new B(); a.h(); // erreur à la compilation même si la classe réelle possède // la méthode h(). En effet la classe déclarée (classe A) // ne ossède pas la méthode h(). En effet, en Java, dès la compilation on doit garantir l’existence de la méthode appelée typage statique) : la classe déclarée de l’objet qui reçoit le message (ici la classe A ou une de ces classes ancêtres (polymorphisme)) doit posséder cette méthode ().
  • 162. Le polymorphisme est obtenu grâce au mécanisme de la liaison retardée (tardive) « late binding »: la méthode qui sera exécutée est déterminée seulement à l’exécution, et pas dès la compilation par le type réel de l’objet qui reçoit le message (et pas par son type déclaré)
  • 163. Mécanisme de la liaison retardée: cas des méthodes redéfinies Soit D la classe réelle d’un objet d (D est la classe du constructeur qui a créé l’objet d) et soit A la classe de déclaration de l’objet d (A d = new D();). Si on a l’instruction: d.f(); quelle méthode f() sera appelée ? 1. Si la méthode f() n’est pas définie dans une classe ancêtre de la classe de déclaration (classe A) alors erreur de compilation. 2. Si non Si la méthode f() est redéfinie dans la classe D, alors c’est cette méthode qui sera exécutée Sinon, la recherche de la méthode f() se poursuit dans la classe mère de D, puis dans la classe mère de cette classe mère, et ainsi de suite, jusqu’à trouver la définition d’une méthode f() qui sera alors exécutée.
  • 164. La méthode appelée ne dépend que du type réel de l’objet et non du type déclaré. Soit B une classe qui hérite de la classe A, et soit f() une méthode définie dans A et redéfinie dans B. Si on a: A a = new B(); a.f(); Alors la méthode f() appelée est celle définie dans B. Si C hérite de B et si la méthode f() est redéfinie dans C, alors si on a: A a = new C(); // Ok car C hérite de B qui hérite de A a.f(); La méthode appelée est celle définie dans C.
  • 165. Utilités du Polymorphisme: Le polymorphisme permet d’éviter les codes qui comportent de nombreux embranchements et tests. Exemple Considérons une classe FormeGeometrique. Supposons que les classes Rectangle et Cercle héritent de la super classe FormeGeometrique. Dans un tableau hétérogène, on ranges des objets de type Rectangle, Cercle. Ensuite on affiche le contenu du tableau
  • 166. Exemple class FormeGeometrique { public void dessineRectangle() {} // méthode vide public void dessineCercle() {} // méthode vide } class Rectangle extends FormeGeometrique { public void dessineRectangle() { System.out.println(&quot;Je suis un rectangle &quot;); } } class Cercle extends FormeGeometrique { public void dessineCercle() { System.out.println(&quot;Je suis un cercle .... &quot;); } }
  • 167. public class TestFigPoly { public static void main(String[] args) { FormeGeometrique [] figures = new FormeGeometrique[3]; figures[0]= new Rectangle(); figures[1]= new Cercle(); figures[2]= new Cercle(); for (int i=0; i < figures.length; i++) { if (figures[i] instanceof Rectangle) figures[i].dessineRectangle(); else if (figures[i] instanceof Cercle) figures[i].dessineCercle(); } } } instanceof: Soit b est une instance d'une classe B alors ( b instanceof A ) retourne true si B est une sous classe de A. En particulier ( b instanceof B ) retourne true.
  • 168. Inconvénients dans le code précédent: Si on veut rajouter une nouvelle forme géométrique par exemple, triangle alors on est obliger de: changer dans le code source aux niveaux définition de la classe (rajouter la méthode vide public void dessineTriangle() {}) Rajouter un branchement pour la forme Triangle Si on traite plusieurs formes géométrique, alors le code comportera plusieurs tests. En exploitant le polymorphisme, on peut améliorer le code précédent Eviter les tests Rendre le code extensible: rajouter de nouvelles sous-classes sans toucher au code existant)
  • 169. L’exemple peut être réécrit de la manière suivante en exploitant le polymorphisme class FormeGeometrique { public void dessineFigure() {} // méthode vide } class Rectangle extends FormeGeometrique { public void dessineFigure() { System.out.println(&quot;Je suis un rectangle &quot;); } } class Cercle extends FormeGeometrique { public void dessineFigure() { System.out.println(&quot;Je suis un cercle .... &quot;); } }
  • 170. public class TestFigPoly { public static void main(String[] args) { FormeGeometrique [] figures = new FormeGeometrique[3]; figures[0] = new Rectangle(); figures[1] = new Cercle(); figures[2] = new Cercle(); for (int i=0; i < figures.length; i++) figures[i].dessineFigure(); // pas besoin de spécifier quelle forme } }
  • 171. Un autre exemple d’exploitation du Polymorphisme: Considérons l’exemple précédent, en supposant que le rectangle et le cercle sont caractérisés par des champs privés qui désignent: La position dans le plan (position du centre) La longueur et la largeur pour le rectangle Le rayon pour le Cercle. Considérons un tableau hétérogène qui contient des formes géométriques différentes: rectangles, cercles, ... Le but et d’afficher le type de la forme géométrique et ses caractéristiques
  • 172. 1 ère solution: class FormeFigure { public void dessineFigure() {} } class Rectangle extends FormeFigure { public Rectangle(int x, int y, int longueur, int largeur) { // centre (x,y) this.x=x; this.y=y; this.largeur=largeur; this.longueur=longueur; } public void dessineFigure() { System.out.println(&quot; Je suis un Rectangle de longueur &quot; +longueur +&quot; et de largeur &quot; + largeur); System.out.println(&quot; ma position dans le plan est (&quot; + x + &quot; ,&quot; + y + &quot;)&quot; ); } private int x,y; private int largeur, longueur; }
  • 173. class Cercle extends FormeFigure { public Cercle(int x, int y, int rayon){ // centre (x,y) this.x=x; this.y=y; this.rayon=rayon; } public void dessineFigure(){ System.out.println(&quot; Je suis un cercle de Rayon &quot; + rayon); System.out.println(&quot; ma position dans le plan est (&quot; + x + &quot; ,&quot; + y + &quot;)&quot; ); } private int x,y; private int rayon; }
  • 174. public class TestFigPolySuite { public static void main(String[] args) { FormeFigure [] figures = new FormeFigure[2]; figures[0]=new Rectangle(1,2,15,6); figures[1]=new Cercle(0,0,4); for (int i=0; i < figures.length; i++) figures[i].dessineFigure(); } }
  • 175. 2 ème solution : on ne redéfinie pas la position dans le plan qui est la même pour toutes les formes géométrique. class FormeFigure { public FormeFigure(int x, int y) { // constructeur this.x=x; this.y=y; } public void dessineFigure() { afficheMonIdentite(); System.out.println(&quot; ma position dans le plan est (&quot; + x + &quot; ,&quot; + y + &quot;)&quot; ); } public void afficheMonIdentite(){}; // méthode vide private int x,y; }
  • 176. class Rectangle extends FormeFigure { public Rectangle(int x, int y, int longueur, int largeur) { // centre (x,y) super(x,y); this.largeur=largeur; this.longueur=longueur; } public void afficheMonIdentite() { System.out.println(&quot; Je suis un Rectangle de longueur &quot; +longueur +&quot; et de largeur &quot; + largeur); } private int largeur, int longueur; } class Cercle extends FormeFigure { public Cercle(int x, int y, int rayon){ // centre (x,y) super(x,y); this.rayon=rayon; } public void afficheMonIdentite() { System.out.println(&quot; Je suis un cercle de Rayon &quot; + rayon); } private int rayon; }
  • 177. public class TestFigPolySuite { public static void main(String[] args) { FormeFigure [] figures = new FormeFigure[2]; figures[0]=new Rectangle(1,2,15,6); figures[1]=new Cercle(0,0,4); for (int i=0; i < figures.length; i++) figures[i].dessineFigure(); // la méthode afficheMonIdentite() appelée est celle définie dans la classe //réelle de l’objet et non celle définie dans la classe de déclaration } }
  • 178. Cast (transtypage) : conversions de classes Le « cast » est le fait de forcer le compilateur à considérer un objet comme étant d’un type qui n’est pas le type déclaré ou réel de l’objet En Java, les seuls casts autorisés entre classes sont les casts entre classe mère et classes filles
  • 179. Syntaxe Pour caster un objet en classe A : (C) o; Exemple : FormeFigure a = new FormeFigure(); Rectangle r = (Rectangle) a; FormeFigure b; (Rectangle) b = r;
  • 180. UpCast : classe fille -> classe mère Upcast : un objet est considéré comme une instance d’une des classes ancêtres de sa classe réelle Il est toujours possible de faire un upcast car tout objet peut être considéré comme une instance d’une classe ancêtre Le upcast est souvent implicite
  • 181. DownCast : classe mère -> classe fille Downcast : un objet est considéré comme étant d’une classe fille de sa classe de déclaration Toujours accepté par le compilateur Mais peut provoquer une erreur à l’exécution ; à l’exécution il sera vérifié que l’objet est bien de la classe fille Un downcast doit toujours être explicite
  • 182. Classes abstraites Une classe abstraite ( abstract class ) est une classe déclarée avec le mot clé abstract class . Par exemple: abstract class A { … } Dans une classe abstraite on peut trouver: des champs, des méthodes et des méthodes abstraites
  • 183. Une méthode est abstraite, lorsqu’on la déclare sans donner son implémentation: on ne fournit que le type de la valeur de retour et la signature (l’entête de la méthode). Les méthodes abstraite sont déclarée avec le mot clè abstract . Exemple: abstract void f( int i, float x); abstract double g(); La méthode peut être implémentée par les classes filles.
  • 184. On peut créer une référence sur un objet de type A (une classe abstraite) mais il est interdit de créer une instance (un objet) d’une classe abstraite A a; // autorisé A a = new A(); // n’est pas autorisé. Si B hérite de A alors on peut écrire: A a = new B(); Une méthode static ne peut être abstraite (car on ne peut redéfinir une méthode static ) Une classe qui contient au moins une méthode abstraite est automatiquement abstraite Une méthode déclarée abstraite doit obligatoirement être déclarée public.
  • 185. Intérêt des classe abstraites: la classe mère définit la structure globale d’un algorithme elle laisse aux classes filles le soin de définir des points bien précis de l