Corrigés des premiers exercices sur les classes

Ce document présente un corrigé d'exercices sur la programmation orientée objet en Java, portant sur la manipulation des classes, des objets, des méthodes, des constructeurs, ainsi que sur la conception d'une architecture logicielle.

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.

Document source

Corrigés des premiers exercices sur les classes

Programming, Object-Oriented Programming, Java · PDF · 9 pages · 2012

Afficher l'aperçu du document

Consulter le document original →

Ce document présente un corrigé d'exercices sur la programmation orientée objet en Java, portant sur la manipulation des classes, des objets, des méthodes, des constructeurs, ainsi que sur la conception d'une architecture logicielle. Ces exercices testent la compréhension des concepts fondamentaux de la programmation orientée objet, la capacité à écrire et analyser du code Java, et la réflexion sur la modélisation d'un problème.

Exercice 2.1.1 utilisation d’une classe

Il s'agit d'analyser et d'utiliser une classe Compte représentant un compte bancaire simple, puis d'écrire du code pour manipuler plusieurs comptes.

Question 1

Comment fonctionne la méthode virement ? Combien de comptes fait-elle intervenir ?

La méthode virerVers fait intervenir deux objets de type Compte :

  • this, l'objet sur lequel la méthode est appelée, c'est-à-dire le compte source.
  • destination, le paramètre de la méthode, c'est-à-dire le compte destinataire.

Le virement consiste à retirer une certaine somme du compte source (this) puis à déposer cette somme sur le compte destinataire (destination).

Réponse : La méthode virement fait intervenir deux comptes, le compte source et le compte destination, en retirant de l'un et déposant sur l'autre.

Question 2

Créer deux comptes, effectuer plusieurs opérations (dépôts, retrait, virement) et afficher les soldes.

Le code Java suivant, placé dans la méthode main d'une classe TesteCompte, réalise ces opérations :

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 du programme :

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

Réponse : Le programme fonctionne comme attendu, avec un solde de 425 euros pour martin et 1065 euros pour jean après les opérations.

Question 3

Créer un tableau de dix comptes, initialiser chacun avec un dépôt de 200 euros plus 100 fois son indice, puis effectuer des virements de 20 euros de chaque compte vers tous les comptes suivants, enfin afficher tous les soldes.

Le code proposé est :

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 du programme :

> run TesteCompte
Compte de martin, solde: 425
Compte de jean, solde: 1065
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
>

Réponse : Le tableau est correctement initialisé, les virements sont effectués entre comptes successifs, et les soldes affichés correspondent aux calculs attendus.

Exercice 2.1.2 constructeurs

Il s'agit d'ajouter un attribut au compte, créer un constructeur, et réfléchir à la gestion du nom du titulaire.

Question 1

Ajouter un attribut String titulaire à la classe Compte et modifier la méthode d'affichage pour afficher ce nom.

La méthode afficher devient :

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

Réponse : L'attribut titulaire est ajouté et affiché correctement.

Question 2

Créer un constructeur prenant en paramètre le nom du titulaire, et montrer un exemple de création d'un compte avec ce constructeur.

Code de la classe :

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 utilisation :

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

Réponse : Le constructeur est correctement défini et utilisé pour initialiser le nom du titulaire.

Question 3

Faut-il prévoir des méthodes permettant de changer le nom du titulaire du compte ?

Réponse : Ce n’est pas évident. Un compte peut-il changer de titulaire ? Une personne peut-elle changer de nom ? Il peut néanmoins être utile de permettre une correction en cas de faute de frappe lors de la saisie.

Réponse : Il est conseillé de prévoir une méthode permettant de modifier le nom pour corriger d’éventuelles erreurs, même si le changement de titulaire n’est pas toujours pertinent.

Exercice 2.1.3 méthodes statiques ou non

Il s'agit d'identifier quelles méthodes d'une classe peuvent être statiques et lesquelles ne le peuvent pas.

La classe étudiée :

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;
    }
  }
}

Analyse :

  • Les méthodes afficher, ajouter et plusGrand utilisent les variables d'instance (x, y, nom) et/ou this. Elles ne peuvent donc pas être statiques.
  • Les méthodes nouveau et compare ne dépendent pas d'un objet particulier et peuvent être déclarées static.

Réponse : afficher, ajouter, plusGrand ne peuvent pas être statiques. nouveau et compare peuvent être statiques.

Exercice 2.1.4 égalité d’objets

On étudie la notion d'égalité en Java à travers une classe Compteur et des comparaisons utilisant == et la valeur interne.

Code principal :

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 de l'exécution :

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

Analyse :

  • Le comparateur == teste l'identité des objets, c'est-à-dire s'ils sont le même objet en mémoire.
  • c1 et c3 sont identiques car c3 = c1.
  • c1 et c2 ont la même valeur interne (même valeur de x), mais ce sont deux objets distincts, donc == retourne faux.
  • La comparaison des valeurs internes est faite avec value().
  • Après incrémentation, la valeur change, donc la comparaison des valeurs internes reflète cela.

Conclusion : Le test == compare l'identité des objets, pas leur égalité en termes d'état. Pour tester l'égalité des valeurs, il faut définir et utiliser la méthode equals.

Exercice 2.1.5 conception

Il s'agit de concevoir l'architecture d'un programme de gestion de cocktails, en identifiant les classes, leurs attributs et méthodes, sans réaliser le programme.

Classes proposées et leurs caractéristiques :

Classe Variables Méthodes
Bouteille nom du produit, quantité restante verser (quantité à verser, void)
Bar liste de bouteilles ajouter une bouteille, jeter une bouteille, rechercher une bouteille par nom
Shaker contenance, liste des ingrédients (nom et quantité), propre (booléen) ajouter un ingrédient, vider le shaker, laver le shaker, vérifier si le shaker respecte la recette
Recette liste des ingrédients avec nom et proportion vérifie (paramètre : shaker, résultat : booléen)

Précisions sur les types et classes auxiliaires :

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

Questions importantes à traiter dans la conception :

  • Faut-il utiliser des entiers ou des nombres à virgule pour les quantités ?
  • Faut-il créer une classe Ingredient pour représenter un ingrédient avec son nom et sa quantité ?
  • Comment gérer les proportions dans les recettes ?

Réponse : La conception proposée est cohérente et modulaire, permettant de gérer les différentes entités du problème avec des responsabilités claires. Les choix de types et structures doivent être précisés selon les besoins fonctionnels.

Méthode

Ce corrigé récompense la maîtrise des concepts fondamentaux de la programmation orientée objet : compréhension des classes et objets, utilisation correcte des méthodes, distinction entre méthodes d'instance et statiques, gestion des constructeurs, et réflexion sur la conception logicielle.

Les erreurs pénalisées sont notamment :

  • Ne pas respecter la distinction entre identité d'objet (==) et égalité d'état (méthode equals).
  • Confondre méthodes statiques et d'instance, notamment en utilisant des variables d'instance dans une méthode statique.
  • Omettre les étapes intermédiaires dans le raisonnement ou dans le code, ce qui nuit à la compréhension.
  • Ne pas tester ou valider le code proposé, notamment en affichant les résultats attendus.
  • Dans la conception, ne pas identifier clairement les responsabilités des classes et leurs relations.

Il est important de suivre les conventions données dans l'énoncé, notamment les noms de méthodes et les signatures, afin de garantir la cohérence avec le cours et les attentes pédagogiques.

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