Ecole des Mines de Nancy


Clinique Informatique
Séance 4
Remarque: Le but n'est pas de "faire" une liste d'exercice, mais de comprendre ce qui se passe. Les exercices doivent servir de support à la discussion, n'hésitez pas à poser des questions !

Objectifs de la séance: classes, objets...



Pour les exercices suivants, on créera un nouveau projet sous Eclipse.



Exercice 1 - rappels de cours

Java fournit des types primitifs de variables (int, double, boolean...). Une variable d'un type donné peut prendre n'importe quelle valeur définie par le type. On peut "enrichir" cette notion de type en définissant des classes qui pourront être les types donnés à des variables. Une variable dont le type est une classe est un objet.
Une classe est définie par des attributs (représentant les données) et des méthodes (représentant les actions sur les données). Les méthodes sont appliquées sur les objets.
On accède aux attributs d'un objet et aux méthodes que l'on peut lui appliquer par le ".", et l'objet sur lequel on applique une méthode est accessible par le mot-clé "this".
Un objet est créé à l'aide d'un constructeur qui "dit à la machine" combien il faut réserver de mémoire pour le représenter. Les constructeurs ont le même nom que la classe.


Exemple:

class MaClasse{
    double x;
    int j;
   
    void affiche() {
       System.out.println("valeur de l'attribut x:"+this.x);
       System.out.println("valeur de l'attribut j:"+this.j);
    }

    MaClasse somme(MaClasse m) {
       MaClasse m2 = new MaClasse();
       m2.x = m.x + this.x;
       m2.j = m.j + this.j;
       return m2;
    }
}

Copiez ce code dans un fichier MaClasse.java (une classe est définie dans un fichier de même nom).
Commentaires sur ce code:
- une classe est introduite par le mot-clé "class".
- les lignes 2 et 3 concernent la définition des attributs de la classe MaClasse: un double nommé x et un entier nommé j. Chaque objet de type MaClasse aura donc un attribut x et un attribut y.
- ensuite figure la définition d'une méthode affiche de MaClasse: elle ne prend pas d'argument et ne renvoie rien (void), elle affiche sur la console les valeurs des attributs de l'objet appelant (voir ci-dessous).
- ensuite, définition d'une méthode somme: elle prend comme argument un objet m de type MaClasse et renvoie un objet de type MaClasse.

Copiez le code suivant dans un fichier TestDeMaClasse.java:

class TestDeMaClasse{
    public static void main(String args[]) {
       MaClasse mc1 = new MaClasse();
       mc1.x = 3.4;
       mc1.j = -5;
       mc1.affiche();  
       MaClasse mc2 = new MaClasse();
       mc2.x = 1.0;
       mc2.j = 1;
       mc2.affiche();
       MaClasse mc3 = new MaClasse();
       mc3 = mc2.somme(mc1);      
       mc3.affiche();
    }
}

Que vous inspire ce code ?


Ajout de constructeurs:  dès que l'on crée une classe, on dispose d'un constructeur par défaut sans argument (ici, appelé par "new MaClasse()" ). On peut créer nos propres constructeurs (qui doivent avoir le même nom que la classe), comme des méthodes de la classe. Petite différence avec les méthodes: les constructeurs n'ont pas de type de retour.

Exemple:
Ajoutez le constructeur suivant:

MaClasse(double a, int b) {
    this.x = a;
    this.j = b;
}

et utilisez-le dans TestDeMaClasse.java.

Néanmoins, maintenant que l'on a précisé un constructeur, le constructeur par défaut (sans argument) n'est plus fourni. On peut en définir un (qui donnera des valeurs par défaut aux attributs), ajoutez:

MaClasse() {
    this.x=0.0;  // vous pouvez bien sûr initialiser comme vous le souhaitez
    this.j=0;
}

et expérimentez dans TestDeMaClasse.java.


Le mot-clé "static": on peut déclarer des variables ou des méthodes d'une classe "statiques": elles existent alors indépendamment de toute instance de la classe. Des variables statiques peuvent servir à partager de l'information entre plusieurs objets instances de la même classe. Voir l'exercice 2.




Exercice 2 - analyse d'un code

fichier CompteBancaire.java:

class CompteBancaire {
    static String Nom = "Compte de la banque de l'EMN";
    String nomclient;
    int solde;
   
    CompteBancaire(String n, int s) {
       this.nomclient = n;
       this.solde = s;
    }
   
    void credite(int somme) {
       this.solde += somme;
    }
      
}

fichier EssaiDeCompteBancaire.java:

class EssaieDeCompteBancaire {
    public static void main(String[] args) {
       System.out.println(CompteBancaire.Nom);
       CompteBancaire compte1 = new CompteBancaire("toto",1000);
       System.out.println(compte1.Nom + " "+ compte1.nomclient + " " + compte1.solde);
       CompteBancaire compte2 = new CompteBancaire("titi",1000);
       compte2.credite(100);
       System.out.println(compte2.Nom + " "+ compte2.nomclient + " " + compte2.solde);  
       compte2.Nom = "changement de nom";
       compte2.nomclient = "tutu";
       System.out.println(CompteBancaire.Nom);
       System.out.println(compte1.Nom);
       System.out.println(compte2.Nom);
       System.out.println(compte1.nomclient);
       System.out.println(compte2.nomclient);
    }
}


Que s'affiche-t-il ? Commentez.




Exercice 3 - classe << Rationnel >>

Écrivez une classe Rationnel permettant de représenter les rationnels (c'est-à-dire les fractions p/q où p et q sont entiers, q non nul), selon les indications suivantes.

Spécification de la classe:
constructeur: Rationnel(int p, int q)
signatures des méthodes:
int numerateur()   renvoie le numérateur de l'appelant;
int denominateur()   pour le dénominateur;
double toDouble()  pour renvoyer un double approchant l'appelant;
void affiche()  pour afficher sur la console le rationnel sous la forme "p / q";
Rationnel oppose()  renvoie l'opposé de l'appelant;
Rationnel inverse()  renvoie l'inverse de l'appelant;
Rationnel somme(Rationnel r)  renvoie un rationnel égal à la somme du rationnel appelant et de r;
Rationnel produit(Rationnel r)  pour le produit.

Ecrivez une classe de test TestRationnel qui comprendra une méthode main pour effectuer des tests.

Ecrivez une méthode statique de la classe TestRationnel (appelée fonction en cours) qui permet de calculer de manière exacte la moyenne d'un tableau de rationnels. 
Sa signature est:
public static Rationnel moyenne(Rationnel[] tab)

Bonus: ajoutez une méthode dans la classe Rationnel qui simplifie les fractions (pensez au calcul du pgcd par l'algorithme d'Euclide).



Contact:
Frédéric Sur, ATER au département d'informatique.