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
Programming, Object-Oriented Programming, Java · PDF · 9 pages · 2012
Afficher l'aperçu du document
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,ajouteretplusGrandutilisent les variables d'instance (x,y,nom) et/outhis. Elles ne peuvent donc pas être statiques. - Les méthodes
nouveauetcomparene dépendent pas d'un objet particulier et peuvent être déclaréesstatic.
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. c1etc3sont identiques carc3 = c1.c1etc2ont la même valeur interne (même valeur dex), 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: Stringquantite: int
- Classe Bouteille :
contenu: Ingredientverser(int quantité): void
- Classe Bar :
reserve: Bouteille[]ajouter(Bouteille): voidjeter(Bouteille): voidchercher(String nom): Bouteille
- Classe Shaker :
contenance: intcontenu: Ingredient[]propre: booleanajouter(Ingredient): voidvider(): voidlaver(): 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éthodeequals). - 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.
Commentaires
Aucun commentaire pour le moment. Posez la première question.