page précédantetable des matièrespage suivante

Les objets dans Java

Déclaration

Java est un langage fondamentalement objet. Les classes peuvent être considérée comme étant les briques d'une application Java.
    classe   =>  méthodes + membres donnée
On utilise les classes pour créer des instances, qui sont des références à des objets utilisés lors de l'exécution qui implémentent la structure de la classe.

Déclaration d'une classe:
   

class Person {
  String name = "namePers";
  int age;
  void growUp()
{
       age ++;
  }
}


 

Les déclarations de variables et de méthodes peuvent apparaître dans n'importe quel ordre, mais lors de l'initialisation des variables, on ne peut pas utiliser des références à des variables pas encore déclarés.
 

Instance d'une classe, constructeur


Pour créer des variables (instances) de la classe Pendule:

    Person p1, p2;

Chaque langage a ces moyens propres de manipuler les données. En Java chaque instance de classe est toujours une référence à un objet. On peut imaginer l'objet comme une poste de télévision et son nom – comme un contrôle à distance. Les instances p1 est p2 de la classe Person représentent des variables qui référencent des objets de type Person mais les objets ne sont pas encore crée et les variables sont "vides" - ne pointent pas sur un objet réel. Pour pouvoir utiliser ces variables il faut créer dynamiquement les objets en "heap" en utilisant le mot - clé  new:

    p1 = new Person ();
    p2 = new Person ();
 
 

Accéder les membres - données

Quand l'objet est créé on peut accéder à ces membres – données (on dit aussi variables d'instances) et ces méthodes:

    p2.age = 21;
    p1.growUp();

Chaque objet possède son propre jeu de membres – données

Comme les membres–donnée, les méthodes sont associées à une objet. Mais chaque objet ne possède pas sa propre copie de la méthode. En effet il n'existe qu'un seule copie de la méthode, mais qui travaille avec les membres – données d'un objet particulier.

Pour pouvoir faire ça, chaque méthode (à l'exception des méthodes statiques) reçois un paramètre implicite (on ne le voit pas)  this qui représente un référence vers l'objet concerné et qui est ajouté automatiquement chaque fois quand on utilise un membre – donnée. Ainsi l'instruction

    age++;

est interprété comme:

    (this.age)++;

On peut utiliser se paramètre aussi bien, explicitement dans le corps de méthode.
 

Initialisation d'objet

L'absence d'initialisation des variables est une des raisons principales pour les "bugs" dans un programme. Java (comme C++) introduit une méthode spéciale appelée "constructeur" qui est lancée chaque fois pendant la construction d'un objet.
a pour but d'initier tous les membres – donnée;
porte exactement le nom de la classe;
n'existe pas un résultat à retourner (même "void").;
existe un constructeur par défaut.
L'initialisation de chaque objet passe quatre étapes:
    1)Réservation la quantité nécessaire de mémoire dans le "heap" pour les variables données;
    2)Tous les variables données sont initiées avec une valeur 0;
    3)On change les valeurs des variables données selon les valeurs introduites dans la dé-claration de la classe;
    4)On lance le constructeur s'il existe pour finir l'initialisation

L'affectation entre deux objet a pour résultat deux références qui pointent sur le même objet:

class Number {
        int i;
}

public class Assignment {
        public static void main(String[] args) {
                Number n1 = new Number();
                Number n2 = new Number();
                n1.i = 9;
                n2.i = 47;
                System.out.println("1: n1.i: " + n1.i +", n2.i: " + n2.i);
                n1 = n2;
                System.out.println("2: n1.i: " + n1.i + ", n2.i: " + n2.i);
                n1.i = 27;
                System.out.println("3: n1.i: " + n1.i + ", n2.i: " + n2.i);
        }
}

Résultat:

        1: n1.i: 9, n2.i: 47
        2: n1.i: 47, n2.i: 47
        3: n1.i: 27, n2.i: 27

les opérateur relationnels '= =' et '!=' ne testent pas les objets mais leur références:

public class Equivalence {
        public static void main(String[] args) {
                Integer n1 = new Integer(47);
                Integer n2 = new Integer(47);
                System.out.println(n1 == n2); //compare des références - faux
                System.out.println(n1 != n2); //compare des références - vrai
        }
}

System.out.println(n1.equals(n2)); //compare des objets - vrai

wrapper classes

A chaque type primitif correspond une classe ("wrapper class") qui permet la création des objets pour présenté se type primitif:

        char c = 'd';
        Character C = new Character(c);

ou bien

    Character C = new Character('d');

Java 1.1 a ajouté deux classe pour arithmétique de haute précision – BigInteger et BigDecimal.
 
 

type primitif
wrapper class
boolean
Boolean
char
Character
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
void
Void
-
BigInteger
-
BigDecimal




Trois reasons pour utiliser  Number à la place de type primitif::
  1. Comme argument d'une méthode qui attend un  object.
  2. Pour utiliser un  constant définit dans la  classe : MIN_VALUE ou bien MAX_VALUE.
  3. Pour utiliser les  méthodes pour conversion des  types, conversion à partir de strings, et pour conversion entre les systems (decimal, octal, hexadecimal, binary).

 
exemple resultats
import java.math.BigInteger; 
public class WrappedClassApp {
   static final int radix = 16;
   public static void main(String args[]) {
      Boolean b1 = new Boolean("TRUE");
      Boolean b2 = new Boolean("FALSE");
      System.out.println(b1.toString()+" or "+b2.toString());
      for(int j=0;j<radix;++j)
           System.out.print(Character.forDigit(j,radix));
      System.out.println();
      System.out.print("Radix between "+ Character.MIN_RADIX);
      System.out.println(" and " + Character.MAX_RADIX);
      Integer i = new Integer(Integer.parseInt("ef",radix));
      Long l = new Long(Long.parseLong("abcd",radix));
      long m=l.longValue()*i.longValue();
      System.out.println("radix=4: "+Long.toString(m,4));
      System.out.println("radix=10: "+Long.toString(m,10));
      System.out.println("radix=16: "+Long.toString(m,16)); 
      System.out.println(Float.MIN_VALUE);
      System.out.println(Double.MAX_VALUE);

      BigInteger n=new BigInteger("1000000000000");
      BigInteger one=new BigInteger("1");
      while(!n.isProbablePrime(7)) n=n.add(one);
      System.out.println("\n"+n.toString(10)+" is probably prime.");
      System.out.println("It is "+n.bitLength()+" bits in length.");}
}

true or false
0123456789abcdef
Radix between 2 and 36
radix=4: 220012101203
radix=10: 10511459
radix=16: a06463
1.4E-45
1.7976931348623157E308

1000000000039 is probably prime.
It is 40 bits in length.

Les modificateurs d'accès

A l'intérieur d'une classe, on peut accéder à tous les membres – données et appeler des méthodes directement par leur nom (accès direct).

L'accès aux membres - données et aux méthodes à l'extérieur des classes Java dépend des modificateurs d'accès. Ces modificateurs définissent divers degrés d'accès aux membres des classes. Les modificateurs d'accès sont indiqués juste avant le type de la variable ou de résultat pour les méthodes. Il existe quatre modificateurs d'accès: par défaut(pas de modificateur), public, protected et private:

par défaut (il n'y a pas de modificateur): seuls les classes de même paquetage peuvent accéder aux membres. 

public: les membres sont accessibles à tous, que ce soit à l'intérieur ou à l'extérieur de la classe ou du paquetage: 

protected: les membres ne sont accessibles qu'aux méthodes dans cette classe et dans les classes dérivés de cette classe ou du paquetage.

private: les membres ne sont accessibles qu'aux méthodes dans la classe où ils ont été définis (accès direct).   
 

Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

 Example:

Classes and Packages of the Example Used to Illustrate Access Levels

Visibility
Modifier Alpha Beta Alphasub Gamma
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

package one;
public class Alpha {
           String name;
    public String fNumber;
    protected int age;
    private String friend;
    public Alpha(){       
    }
    public Alpha(String name,String fn,int age,String friend){
        this.name=name;
        fNumber=fn;
        this.age=age;
        this.friend=friend;
    }
    public String getFriend(){
        return friend;
    }
}
================================================
package one;
public class Beta {
    public static void main(String [] arg){
        Alpha alpha = new Alpha("Pijo","1234",19,"Penda");
        System.out.println (alpha.name);
        System.out.println (alpha.fNumber);
        System.out.println (alpha.age);
        //System.out.println (alpha.friend);  error
        System.out.println (alpha.getFriend());
       
    }
}
package two;
public class AlphaSub extends one.Alpha{
    AlphaSub(String name,String fn,int age,String friend){
        super(name,fn,age,friend);
    }
    public static void main(String [] arg){
        AlphaSub alpha = new AlphaSub("Pijo","1234",19,"Penda");
        //System.out.println (alpha.name);   error
        System.out.println (alpha.fNumber);
        System.out.println (alpha.age);       // accessible
        //System.out.println (alpha.friend);  error
        System.out.println (alpha.getFriend());       
    }
}




================================================
package two;

public class Gama {
    public static void main(String [] arg){
        AlphaSub alpha = new AlphaSub("Pijo","1234",19,"Penda");
        //System.out.println (alpha.name);   error
        System.out.println (alpha.fNumber);
        //System.out.println (alpha.age);   error
        //System.out.println (alpha.friend);  error
        System.out.println (alpha.getFriend());       
    }
}

 
 

Les membres static

class Exemple {

        int m3=1;
        static int m2=3;
        static void func() {
                Exemple e1 = new Exemple();
                Exemple e2 = new Exemple();
                int k = m2; //l'accès direct
                int n = e1.m3; //l'accès par la référence d'un objet
                …
        }…
}


 

Quand on déclare un membre - donnée comme étant static, on ne lui alloue de la mémoire qu'une seule fois, indépendamment de nombre d'objets effectivement instanciés.

Tous les objets de la classe partagent le même membre static. Une méthode static est une méthode qui ne reçoit pas this comme paramètre, donc elle n'a accès direct qu'aux membres statiques. Pour l'accéder à une membre non static elle doit utiliser la référence d'un objet de la classe.

Les modificateurs final, synchronized et native

final: spécifie qu'une membre – donnée a une valeur constante (initialisée au moment de sa déclaration) ou qu'une méthode ne peut pas être redéfinie dans un sous-classe. Pour ainsi dire, final indique qu'un membre d'une classe est dans sa version définitive.

synchronized: spécifie qu'une méthode est "mono-thread". A un moment donné, une seule exécution est autorisée pour une méthode synchronized.

native: spécifie que la méthode est implémenté en C et se trouve dans un fichier exécutable. Les déclaration de la méthode n'a pas un corps:

        native int Cprogramme();

Les tableaux

La déclaration d'un tableau se fait à l'aide d'une paire de crochets:

        int nombre[ ];
        long grille [ ], jours [ ];

En différence de C, les tableaux de langage Java sont des objets de la classe tableau. Ces déclarations n'introduisent que des références des tableaux et n'allouent aucune place dans la mémoire, donc on ne peut pas indiquer le nombre des élément dans la déclaration. A fin d'allouer la place pour ces tableau, soit on doit utiliser l'opérateur new:

        int nombre[ ] = new int[10]; //un tableau de dix éléments

soit on doit affecter une série d'éléments au tableau au moment de sa création:

        char voyelle[ ] = {'a', 'e', 'i', 'o', 'u'}; // un tableau de cinq éléments

La taille d'un tableau est disponible grâce à la variable publique length:

        int longueur = voyelle.length; //longueur = 5

Esayer d'acceder à un élément qui est à l'extérieur du tableau génère une exception ArrayIndexOutOfBoundsException de type RuntimeException.

La méthode arraycopy() de la classe System sert pour copier un certain nombre d'éléments d'un tableau dans un autre:

        System.arraycopy (objetsSource, positionSource, objetdDestination, positionDéstination, longueur)

Par exemple pour ajouter un élément aux tableau voyelle:

        char voyelle[ ] = {'a', 'e', 'i', 'o', 'u'};
        char tmp[ ] = new char[voyelle.length+1];
        System.arraycopy(voyelle, 0, tmp, 0, voyelle.length);
        tmp[voyelle.lemgth] = 'y';
        voyelle=tmp;

Il n'y a plus de références sur l'ancien objet et il sera récupéré par le ramasse-miette

Parcours de tableau

Pour parcourir complètement ou partiellement un tableau, il suffit simplement d'utiliser une boucle for. Voici un exemple qui parcoure complètement un tableau pour l'afficher à la console :

 

public class Array{ 
   public static void main(String a[]){ 
      int ar[] = {-3,4,-17,2,-1,8};
      for(int i =0; i< ar.length;i++){
           System.out.println("   "+ar[i]); 
      }
  
}
-3  4  -17  2   -1  8

Il ne faut pas oublier que le premier indice du tableau est 0, ensuite on parcoure toutes les positions jusqu'à atteindre tab.length - 1.

Boucle for améliorée Java 5.0

Java 5.0 offre une nouvelle boucle for qui permet de facilement parcourir tous les objets qui représentent des collections d'objets. Le listing suivant donne la syntaxe de cette boucle for.

for (<type_de_donnée>  <nom_variable> : <collection_à_parcourir>)
{
        // Corps de la boucle
}

public class Array{ 
   public static void main(String a[]){ 
      int ar[] = {-3,4,-17,2,-1,8};
      for(int el :ar){
           System.out.println("   "+el); 
      }
  
}
-3  4  -17  2   -1  8

Java gère les tableaux à plusieurs dimensions avec des objets qui sont des tableaux de tableaux. La syntaxe est ressemblant à celle de C:

        int matrice [ ] [ ];
        matrice = new int [8][8];
        matrice[0][0] = 3;
        matrice [0][1] = 5;
        …

On peut créer des tableaux dont les lignes n'ont pas forcément la même taille:

        int ex[][] = new int[3][ ];
        ex[0] = new int [3];
        ex[1] = new int[5];
        ex[2] = new int[4];
 
 
0
0
0
   
0
0
0
0
0
0
0
0
0
 

 
 

Example
 
public class Array{ 
   public static void main(String a[]){ 
      int ar[][] = {{3,4},{17,2,1,8}}; 
      for(int i =0; i< ar.length;i++){ 
         for(int j = 0;j< ar[i].length; j++) System.out.print(" "+ar[i][j]); 
         System.out.println(); 
     
  
}
3 4 
17 2 1 8 

Boucle for améliorée Java 5.0


public class Array_s {
       public static void main(String a[]){
              String ar[][] = {{"Koko","Kiko","Kako"},{"Simo", "Sima"}};
              for(String[] line :ar){
                  for(String el:line)
                   System.out.print("   "+el);
                  System.out.println();
              }
           }
}
   Koko   Kiko   Kako
   Simo   Sima

Lists

Une liste est une collection d' qui est par définition une collection ordonnée, également connu en tant que séquence. Contrairement au tableau, le nombre d'éléments dans la liste peut être réduit ou agrandi.

Une collection Liste ne peut contenir  que des objets.

Il existe deux implémentations de liste à usage général - ArrayList et LinkedList. Le plus utilisée, est ArrayList. Il offre un accès en temps constant de position, et il peut profiter de System.arraycopy quand il doit déplacer plusieurs éléments en même temps.

List<Object> listOfObjects = new ArrayList<Object>(); 

class Person{
            ...
        }
        class Student extends Person{
            ...
        }
        List<Person> listOfPersons = new ArrayList<Person>();

Utilisation

Exemple
import java.util.*;
public class ListDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      System.out.println("initial size:"+al.size());
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");
      System.out.println("the new size:"+al.size());
      for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
      }
     String ex = al.remove (2);
     System.out.println("removing value:"+ex);
     System.out.println("size after remove:"+al.size());
     for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
     }
   }
}
initial size:0
the new size:6
C
A
E
B
D
F
removing value:E
size after remove:5
C
A
B
D
F

Iterateurs

import java.util.*;
public class IteratorDem {
    public static void main(String arg[]){
        // Create an array list
          ArrayList <String>  al = new ArrayList <String>();
          // add elements to the array list
          al.add("C");
          al.add("A");
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
          ListIterator<String> litr = al.listIterator();
         // litr.set("new");             error- there is no element in the iterator
         
         
          System.out.println("before element "+litr.nextIndex());
          System.out.println("after element "+litr.previousIndex());
         
          System.out.println(litr.next());
          System.out.println("before element "+litr.nextIndex());
          System.out.println("after element "+litr.previousIndex());
         
          litr.set("modified");     // modify the last element returned
                                          // by next() or previous()
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
    }
}
ArrayList:C A
before element 0
after element -1
C
before element 1
after element 0
ArrayList:modified A

import java.util.*;
public class IteratorDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");

      // Use iterator to display contents of al
      System.out.print("Original contents of al: ");
      Iterator<String> itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();
     
      // Modify objects being iterated
      ListIterator<String> litr = al.listIterator();
      while(litr.hasNext()) {
         String element = litr.next();
         litr.set(element + "+");
      }
      System.out.print("Modified contents of al: ");
      itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();

      // Now, display the list backwards
      System.out.print("Modified list backwards: ");
      while(litr.hasPrevious()) {
         String element = litr.previous();
         System.out.print(element + " ");
       }
       System.out.println();
    }
}

Les chaînes

En Java le chaînes sont gérées par une classe spécifique appelée "String". Même les littéraux de type chaîne sont géré de façon interne comme des objets de cette classe.

Les chaînes de caractères sont inaltérables: une fois créé un objet String on ne peut pas changer sa valeur. Les opérations qui permettent de changer les caractères ou la taille d'une chaîne renvoient un nouvel objet String.

        String chaine = "exemple de création une chaîne";
        int longueur = chaine.length();
        String concatenation = "Pierre" + " et Marie";

On peut construire un objet String d'un tableau de caractères ou d'un tableau de nombres:
class CreateString{
   public static void main(String[] a){
      char datac[ ] = {'p', 'a', 'r', 'c'};
      String sc = new String(datac); //tableau entier
      byte datad [ ] = {65,66,67}; //'A','B', 'C'
      String sd = new String(datad, 0,3); //tableau, debut, longuer
      byte datao [ ] = {065,066,067,064}; //'5', '6', '7', '4'
      String so = new String(datao, 0,3);
      byte datah [ ] = {0x65,0x66,0x67}; // 'e', 'f', 'g'
      String sh = new String(datah, 0,3);
      System.out.println(" c:"+sc+ "\n 8:"+so+"\n 10:"+sd+"\n 16:"+sh);
   }
}
 c:parc
 8:567
 10:ABC
 16:efg

 

Conversion vers une chaîne

La méthode statique String.valueOf() permets la conversion des types différents sous la forme d'une chaîne de caractères.

        String one = String.valueOf(1);

Tous les objets Java possèdent une méthode toString() héritée de la classe Objet qui est utilisée par String.valueOf() pour la présentation sous forme de chaîne.

Conversion à partir d'une chaîne

Pour faire cette conversion on utilise les méthodes valueOf() qui sont fournit par les classes enveloppes (wrapper):

        int i = Integer.valueOf("126").intValue();            //racine = 10
        float f = Float.valueOf("14.75").floatValue();       //racine = 10
        int k = Integer.parseInt("234");                            //racine = 10
        int j = Integer.parseInt("ef",racine);
        long l = Long.parseLong("abcd",racine);

racine  - le racine du systeme dont la valeur est entre Character.MIN_RADIX et Character.MAX_RADIX (2 et 32).

Examples:

 parseInt("0", 10)                        -> 0
 parseInt("473", 10)                    -> 473
 parseInt("-0", 10)                       -> 0
 parseInt("-FF", 16)                    -> -255
 parseInt("1100110", 2)             -> 102
 parseInt("2147483647", 10)    -> 2147483647
 parseInt("-2147483648", 10)    -> -2147483648
 parseInt("2147483648", 10)    jette une NumberFormatException
 parseInt("99", 8)                        jette une NumberFormatException
 parseInt("Kona", 10)                 jette une NumberFormatException
 parseInt("Kona", 27)                -> 411787

Comparaisons

On ne peut pas utiliser les opérateurs relationnels.

méthode equals(), equalsIgnoreCase(), compareTo().

        String un = "truc";
        String deux = "truc";
        String trois = "TRUC";
        if (un == deux)         //faux
        if(un.equals(deux))     //vrai
        if (un.equalsIgnoreCase(trois))     //vrai
        if(un.compareTo(trois) > 0)     //vrai
        if(un.compareTo(deux) ==0)     //vrai

Exemple
 
public class stringExem{
   public static void main(String a[]){
         String names [ ] = {"Rose","Anabelle", "Gerard", "Francoise", "Erik","Constance"},name;
         for(boolean ok = false; !ok; ){
              ok=true;
              for(int i = 0; i < names.length-1; i++){
                    if(names[i].compareTo(names[i+1])>0){
                        name = names[i];
                        names[i] = names[i+1];
                        names[i+1] = name;
                        ok = false;
                    }
              }
         }
         for(int i = 0; i <names.length;i++)
            System.out.println (names[i] + " : "+names[i].length()+" lettres");
    }
}
Anabelle : 8 lettres
Constance : 9 lettres
Erik : 4 lettres
Francoise : 9 lettres
Gerard : 6 lettres
Rose : 4 lettres

Cetains méthodes utiles:

public char charAt(int index)
public boolean endsWith(String suffix)
public int indexOf(String str)
public int indexOf(String str,int fromIndex)
public int lastIndexOf(String str)
public String replace(char oldChar,char newChar)
public boolean startsWith(String prefix)
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
public String toUpperCase()
public String toLowerCase()
public String trim()

page précédantetable des matièrespage suivante