Corrigés des premiers exercices sur les classes

Ce laboratoire propose une série d'exercices corrigés sur la programmation orientée objet en Java, centrés sur la création et l'utilisation de classes. Il aborde la manipulation d'objets, les constructeurs, les méthodes statiques, la notion d'égalité d'objets, ainsi que la conception d'une architecture logicielle simple.

D'après le document Corrigés des premiers exercices sur les classes

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Corrigés des premiers exercices sur les classes

Document source

Corrigés des premiers exercices sur les classes

Programming, Math, etc. · PDF · 2 pages · 2012

Afficher l'aperçu du document

Consulter le document original →

Ce laboratoire propose une série d'exercices corrigés sur la programmation orientée objet en Java, centrés sur la création et l'utilisation de classes. Il aborde la manipulation d'objets, les constructeurs, les méthodes statiques, la notion d'égalité d'objets, ainsi que la conception d'une architecture logicielle simple. Pour réaliser ces exercices, il est nécessaire de disposer d'un environnement Java fonctionnel et de connaissances de base en programmation orientée objet.

Objectifs

  • Comprendre et utiliser une classe simple représentant un compte bancaire.
  • Créer et manipuler des objets, y compris dans des tableaux.
  • Définir et utiliser des constructeurs.
  • Distinguer méthodes statiques et non statiques.
  • Comprendre la notion d'égalité d'objets en Java.
  • Concevoir l'architecture d'un programme orienté objet.

Prérequis et installation

  • Environnement de développement Java (JDK) installé.
  • Connaissances de base en Java : classes, méthodes, variables d'instance.
  • Notions élémentaires sur la programmation orientée objet.
  • Terminal ou console pour exécuter les programmes.

Utilisation d’une classe représentant un compte bancaire

Dans cet exercice, on manipule une classe Compte qui modélise un compte bancaire simple avec un solde et des opérations classiques : dépôt, retrait, virement et affichage du solde.

La méthode virerVers réalise un virement d'un compte vers un autre en retirant une somme du compte appelant (this) et en la déposant sur le compte destination passé en paramètre.

class Compte {
  int solde = 0;

  void deposer(int montant) {
    solde = solde + montant;
  }

  void retirer(int montant) {
    solde = solde - montant;
  }

  void virerVers(int montant, Compte destination) {
    this.retirer(montant);
    destination.deposer(montant);
  }

  void afficher() {
    Terminal.ecrireString("solde: " + solde);
  }
}

Pour tester cette classe, créez deux comptes, effectuez des opérations et affichez les soldes :

public class TesteCompte {
  public static void main(String[] args) {
    Compte martin, jean;

    martin = new Compte();
    jean = new Compte();

    // dépôt de 500 euros sur le premier compte.
    martin.deposer(500);

    // dépôt de 1000 euros sur le second compte.
    jean.deposer(1000);

    // retrait de 10 euros sur le second compte.
    jean.retirer(10);

    // virement de 75 euros du premier compte vers le second.
    martin.virerVers(75, jean);

    // affichage des soldes des deux comptes.
    Terminal.ecrireString("Compte de martin, ");
    martin.afficher();
    Terminal.sautDeLigne();

    Terminal.ecrireString("Compte de jean, ");
    jean.afficher();
    Terminal.sautDeLigne();
  }
}

Exécution attendue :


> run TesteCompte
Compte de martin, solde: 425
Compte de jean, solde: 1065

Manipulation d’un tableau de comptes

Créez un tableau de dix comptes. Chaque compte reçoit un dépôt initial de 200 euros plus 100 fois son indice dans le tableau. Ensuite, chaque compte effectue un virement de 20 euros vers tous les comptes qui le suivent dans le tableau.

Compte[] table = new Compte[10];

for (int i = 0; i < table.length; i++) {
  table[i] = new Compte();
  table[i].deposer(200 + i * 100);
}

for (int i = 0; i < table.length; i++) {
  for (int j = i + 1; j < table.length; j++) {
    table[i].virerVers(20, table[j]);
  }
}

for (int i = 0; i < table.length; i++) {
  Terminal.ecrireString("Compte numero " + i + ", ");
  table[i].afficher();
  Terminal.sautDeLigne();
}

Exécution attendue :


Compte numero 0, solde: 20
Compte numero 1, solde: 160
Compte numero 2, solde: 300
Compte numero 3, solde: 440
Compte numero 4, solde: 580
Compte numero 5, solde: 720
Compte numero 6, solde: 860
Compte numero 7, solde: 1000
Compte numero 8, solde: 1140
Compte numero 9, solde: 1280

Ajout d’un constructeur et du nom du titulaire

On complète la classe Compte en ajoutant un attribut titulaire de type String et un constructeur qui initialise ce nom. La méthode d'affichage est modifiée pour afficher le nom du titulaire en plus du solde.

class Compte {
  int solde = 0;
  String titulaire;

  Compte(String n) {
    titulaire = n;
  }

  void depot(int montant) {
    solde = solde + montant;
  }

  void retrait(int montant) {
    solde = solde - montant;
  }

  void virement(int montant, Compte autre) {
    autre.retrait(montant);
    this.depot(montant);
  }

  void afficher() {
    Terminal.ecrireString("Compte de " + titulaire + ", solde: " + solde);
  }
}

Exemple de création et test :

public class Exo13_2 {
  public static void main(String[] argv) {
    Compte unCompte = new Compte("Jean Delacroix");
    unCompte.depot(700);
    unCompte.afficher();
    Terminal.sautDeLigne();
  }
}

Discussion sur la modification du nom du titulaire

Faut-il prévoir une méthode pour changer le nom du titulaire ? Cela dépend du contexte métier : un compte peut-il changer de titulaire ? Une personne peut-elle changer de nom ? Il peut être utile de prévoir un moyen de corriger une faute de frappe lors de la saisie.

Méthodes statiques ou non

Analyse d’une classe avec plusieurs méthodes pour déterminer lesquelles peuvent être statiques :

class Exo13_3 {
  int x, y;
  String nom;

  void afficher() {
    Terminal.ecrireString(nom + " " + x + " " + y);
  }

  void ajouter(Exo13_3 obj) {
    x = x + obj.x;
    y = y + obj.y;
    nom = nom + obj.nom;
  }

  Exo13_3 nouveau(int n) {
    Exo13_3 res = new Exo13_3();
    res.x = n;
    res.y = n * 2;
    res.nom = "Auto_" + n;
    return res;
  }

  boolean plusGrand(Exo13_3 obj) {
    if (obj.x == x) {
      return y > obj.y;
    } else {
      return x > obj.x;
    }
  }

  boolean compare(Exo13_3 obj1, Exo13_3 obj2) {
    if (obj1.x == obj2.x) {
      return obj1.y > obj2.y;
    } else {
      return obj1.x > obj2.x;
    }
  }
}

Les méthodes afficher, ajouter et plusGrand utilisent des variables d’instance et ne peuvent pas être statiques. Les méthodes nouveau et compare peuvent être déclarées statiques car elles n’utilisent pas this ni les variables d’instance.

Égalité d’objets en Java

Ce programme illustre la différence entre l’égalité d’identité (avec ==) et l’égalité de valeur :

class Compteur {
  int x;

  Compteur(int n) {
    x = n;
  }

  Compteur incremente() {
    x++;
    return this;
  }

  int value() {
    return x;
  }
}

public class Exo13_4 {
  public static void main(String[] argv) {
    Compteur c1, c2, c3;
    c1 = new Compteur(0);
    c1.incremente();
    c2 = new Compteur(1);
    c3 = c1;

    if (c1 == c3) {
      Terminal.ecrireStringln("c1 et c3 sont egaux");
    } else {
      Terminal.ecrireStringln("c1 et c3 ne sont pas egaux");
    }

    if (c1.value() == c2.value()) {
      Terminal.ecrireStringln("c1 et c2 ont meme valeur");
    } else {
      Terminal.ecrireStringln("c1 et c2 n’ont pas la meme valeur");
    }

    if (c1 == c2) {
      Terminal.ecrireStringln("c1 et c2 sont egaux");
    } else {
      Terminal.ecrireStringln("c1 et c2 ne sont pas egaux");
    }

    if (c1.value() == c1.incremente().value()) {
      Terminal.ecrireStringln("c1 et c1 incremente ont meme valeur");
    } else {
      Terminal.ecrireStringln("c1 et c1 incremente n’ont pas la meme valeur");
    }

    if (c1 == c1.incremente()) {
      Terminal.ecrireStringln("c1 et c1 incremente sont egaux");
    } else {
      Terminal.ecrireStringln("c1 et c1 incremente ne sont pas egaux");
    }
  }
}

Résultat attendu :


c1 et c3 sont égaux
c1 et c2 ont même valeur
c1 et c2 ne sont pas égaux
c1 et c1 incremente n’ont pas la même valeur
c1 et c1 incremente sont égaux

Le test == compare l'identité des objets (leur référence mémoire), pas leur contenu. Ainsi, deux objets distincts avec les mêmes valeurs sont considérés différents. Pour comparer les valeurs, il faut utiliser la méthode equals (non définie ici). Ce comportement est important à comprendre pour éviter des erreurs dans les comparaisons d'objets.

Conception d’une application de gestion de cocktails

Cette réflexion porte sur la structuration d’un programme orienté objet pour gérer un bar, des bouteilles, des shakers et des recettes de cocktails.

Classes proposées et leurs attributs

  • Bouteille : nom du produit, quantité restante.
  • Bar : liste de bouteilles.
  • Shaker : contenance, liste des ingrédients (nom et quantité), état de propreté.
  • Recette : liste des ingrédients avec proportions.
  • Ingredient : nomProduit (String), quantite (int).

Méthodes principales

  • Bouteille : verser une certaine quantité.
  • Bar : ajouter une bouteille, jeter une bouteille, rechercher une bouteille par nom.
  • Shaker : ajouter un ingrédient, vider, laver, vérifier conformité à une recette.
  • Recette : vérifier si un shaker respecte la recette.

Questions de conception

Il faut décider des types des variables (entiers ou nombres à virgule pour les quantités) et éventuellement créer une classe Ingredient pour représenter un ingrédient avec son nom et sa quantité. Ces choix influencent la clarté et la maintenabilité du programme.

Résumé des classes avec types et méthodes

Classe Attributs Méthodes
Ingredient nomProduit : String
quantite : int
Bouteille contenu : Ingredient verser(int quantité) : void
Bar reserve : Bouteille[] ajouter(Bouteille) : void
jeter(Bouteille) : void
chercher(String nom) : Bouteille
Shaker contenance : int
contenu : Ingredient[]
propre : boolean
ajouter(Ingredient) : void
vider() : void
laver() : void
Recette ingredients : Ingredient[] verifie(Shaker) : boolean

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions