Série d'exercices Java sur la programmation orienté objet POO
Rédigé par GC Team, Publié le 20 Mars 2010, Mise à jour le Mercredi, 16 Avril 2025 01:30
Exercice Java POO sur les constructeurs
Question 1
Voici un programme qui illustre le comportement des constructeurs avec des appels au constructeur de la super-classe (super). Ce programme se focalise sur les constructeurs, il n’y a rien d’autre dans les classes.
1 |
class Premiere { |
1. dessinez le graphe d’héritage de ce programme, retraçant les relations d’héritage entre classes sans
oublier Object, la super-classe de Premiere.
2. prédisez ce que ce programme affiche.
3. compilez et exécutez ce programme pour vérifier vos prédictions.
4. y a-t-il un constructeur qui s’exécute sans afficher de message à la création de certains objets ?
Question 2{sidebar id=8}
1 |
class Cinquieme extends Premiere { |
1. prédisez ce que ce programme affiche.
2. compilez et exécutez ce programme pour vérifier vos prédictions.
Question 3
Le programme suivant provoque une erreur à la compilation : la classe Huitieme est incorrecte
1 |
class Septieme ext nds Premiere { |
Essayez de trouver l’erreur. Si vous n’y arrivez pas, essayez de compiler ce programme : le message
d’erreur peut vous mettre sur la voie.
Question 4{sidebar id=1}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Neuvieme extends Premiere { Neuvieme ( i n t i ) { Terminal.ecrireStringln ( " premier constructeur de Neuvieme " ) ; } Neuvieme ( boolean b ) { Te rminal.ecrireStringln(" second constructeur de Neuvieme " ) ; } } class Dixieme extends Neuvieme { Dixieme ( double d ) { super ( t rue ) ; Terminal . ecrireStringln ( " premie rconstructeur de Dixieme " ) ; } Dixieme ( int x , boolean y ) { super ( x ) ; Terminal . ecrireStringln ( " second constructeur de Dixieme " ) ; } } class Exo19_1_4{ public static void main ( [ ] args ) { new Dixieme ( 1 0 . 5 ) ; Terminal . ecrireStringln ( "=============================" ) ; new Dixieme ( 4 5 , true ) ; }} |
1. prédisez ce que ce programme affiche.
2. compilez et exécutez ce programme pour vérifier vos prédictions.
Exercice JAVA POO sur les classes et l' heritage - volaille -
Programme JAVA - programmation orienté objet
Un éleveur de volaille reçoit d’un fournisseur de jeunes canards et de jeunes poulets qu’il élève jusqu’à
ce qu’ils aient la taille nécessaire à leur commercialisation.
Une volaille est caractérisée par son poids et un numéro d’identification reporté sur une bague qu’elle
porte a sa petite patte. Les volailles arrivent à l’élevage à l’âge de trois semaines. Elles sont baguées et
enregistrées dans le système informatique.
Il y a deux sortes de volailles : des canards et des poulets. Le prix du canard et celui du poulet sont deux
prix différents, exprimés en euros par kilo. En revanche, le prix est le même pour tous les individus de la
même espèce. Ce prix varie chaque jour. Le poids auquel on abat les bêtes est différents pour les canards et
les poulets, mais c’est le même pour tous les poulets (respectivement, tous les canards).
Ecrivez une classe des volailles avec deux sous-classes des poulets et des canards. Il faut pouvoir enregistrer
les prix du jours, les poids d’abbatage, le poids d’une volaille donnée.
Ecrivez une classe permettant de représenter l’ensemble des animaux de l’élevage au moyen d’un tableau.
Des méthodes doivent permettrent de trier les animaux à abattre et d’évaluer le prix obtenu pour ces
animaux. Il faut également pouvoir enregistrer les jeunes animaux qui arrivent.
| {sidebar id=6}{sidebar id=1} |
Exercice en Java POO sur les tableaux et les objets
Exercice 1 : dessin
Pour cet exercice, vous allez dessiner des structures de données au moyen de petits schémas analogues
à ceux du cours.
Question 1 : tableaux
Dessinez chacun des tableaux du programme suivant tels qu’ils sont à la fin de l’exécution de ce programme {sidebar id=8}
1 |
class Exo_16_1_1{ |
Question 2 : objets
Même question pour les variables du programme suivant (var1, var2, var3, cou1, cou2, cou3, cou4, cou5,
cou6
1 |
class Exo_16_1_2{ |
Question 3 : tableaux d’objets
Même question pour les variables du programme suivant.
1 |
class Exo_16_1_3{ |
Question 4 : objets contenant des tableaux
Même question pour les variables du programme suivant.
1 |
class Exo_16_1_4{ |
Exercice 2 : comptes bancaires
On va représenter des comptes bancaires et des titulaires de comptes. Un même compte peut avoir
plusieurs titulaires (c’est le cas par exemple des comptes joints pour un couple). Dans ce cas, le même objet
sera partagé entre les titulaires. Un titutlaire peut avoir plusieurs comptes.
On vous propose le squelette de classe suivant pour implémenter les comptes et les titulaires.
1 |
class TableauCompte { |
Question 1 : création de comptes
Ajouter à ce squelette de classes des méthodes. Seule la banque peut créer des nouveaux comptes.{sidebar id=1}
Quand elle crée un nouveau compte, elle l’ajoute à la liste des comptes de chacun des titulaires de ce compte et elle l’ajoute aussi à sa propre liste de comptes. Par exemple, si une banque b crée un compte c pour les titulaires t1 et t2, le même objet c sera ajouté à trois tableaux : b.tous, t1.mesComptes et t2.mesComptes. Dans chacun de ces trois tableaux, il y aura la même adresse, celle de l’objet c.
Pour réaliser cette création de comptes, il faut une méthode dans Banque qui crée un compte avec en paramètre la liste des titulaires (par exemple sous forme de tableau). Il peut également être utile d’écrire une méthode permettant d’ajouter un nouveau compte chez un titulaire.
Question 2 : variables
Ecrivez une méthode main qui réalise une situation où trois titulaires, Paul, Pierre et Fatima ont des comptes dans une banque BNP. Paul et Fatima ont un compte joint. Fatima a en plus un compte personnel, de même que Pierre.
Dessinez la situation en faisant apparaître sur un schéma tous les objets et tableaux.
Question 3 : virements
On désire écrire une méthode qui permette de faire un virement depuis un compte dont on est titulaire vers un compte dont on ne connaît que le numéro (et dont on n’est pas forcément titulaire) et la banque (autrement dit, on ne connaît pas son adresse). Dans quelle classe faut-il ajouter cette méthode ? Ecrivez cette méthode.
Exercices Java POO programme mari et femme - notion de référence , exception
Exercice 1 : comptes bancaires (suite)
Cet exercice reprend et développe l’exercice precedent. Pour le réaliser, on utilisera le corrigé de cet exercice.
Nous allons développer cet exemple en introduisant une nouvelle notion : celle de procuration. En plus des comptes dont elle est titulaire, une personne peut avoir une procuration sur le compte d’une autre personne. Cela lui permet de faire des opérations sur le compte (par exemple des dépôts et des retraits), mais elle n’a pas le droit de donner à son tour procuration sur ce compte. Seul un des titulaires peut donner procuration sur un compte.
Exercice 2 : mari et femme
| {sidebar id=6}{sidebar id=1} |
Il est possible en java d’avoir une variable d’instance, dans un objet, qui est du même type que l’objet qui la contient. Cela est possible grâce à la notion de référence : la variable ne contient pas l’objet lui-même mais un moyen de le retrouver. Par ailleurs, la valeur null permet de créer le premier objet de la classe en question. Sa variable ne peut pas être initialisée (sauf éventuellement par lui-même, ce qui est possible). Nous allons utiliser cette possibilité pour créer une classe UnePersonne, qui contiendra comme informations
le nom, l’âge et le sexe de la personne et le conjoint (mari ou femme).
Question 1
Faites une première version du programme où seul le nom du conjoint apparaît dans la classe UnePersonne. La classe comportera une méthode pour marier la personne à quelqu’un (un autre objet instance de la classe UnePersonne) et une autre pour faire divorcer la personne. Il y aura des exceptions pour empêcher que les mineurs de moins de 18 ans se marient, pour empêcher que les gens déjà mariés ne se remarient et pour empêcher les gens non mariés de divorcer.
Question 2
Changez le classe obtenue à la question 1 en remplaçant dans la classe le nom du conjoint par une référence à l’objet qui représente le conjoint. On a beaucoup plus d’information sur le conjoint, ce qui permet de vérifier notamment que les deux personnes sont de sexe opposés. Vous traiterez cela avec une exception.
Question 3
On cherche à présent à assurer que les informations de mariage et de divorce soient cohérentes, c’est à dire que quand a a pour conjoint b, il faut que b ait pour conjoint a. D’autre part, si a divorce de b, alors b ne doit plus avoir pour conjoint a. Il faut pour cela que les méthodes de mariage et de divorce changent non seulement l’objet sur lequel elles sont appelées, mais aussi leur paramètre.
Exercice Java POO : comptes bancaires - classes, methodes, constructeurs, sous-classe
Exercice 1 : comptes bancaires
On reprend les classes de comptes bancaires du cours (chapitre 16) : CompteBancaire,CompteAvecDecouver
CompteRemunere, CompteRemunereAvecDecouvert.
Voici un morceau de code avec des inconnues :
1 |
class Exo14_1{ |
Donnez toutes les combinaisons de classes possibles pour XXX, YYY, ZZZ et TTT (vous ne vous
préoccuperez pas des paramètres des constructeurs pour YYY et TTT).
Exercice 2 : des personnes bien nées
On définit comme suit une classe de personnes : {sidebar id=8}
1 |
class LaDate { |
Pour certaines personnes, on connaît en plus le lieu de naissance, mais par pour toutes.
Ecrire une sous-classe des personnes dont on connaît le lieu de naissance. Redéfinir la méthode ecrire pour que le lieu de naissance s’affiche. Ecrivez un petit programme qui utilise la nouvelle sous-classe.
Exercice 3 : des employés
Une entreprise a un certain nombre d’employés. Un employé est connu par son nom, son matricule (qui l’identifie de façon unique) et son indice salairial. Le salaire est calculé en multipliant cet indice par une certaine valeur qui peut changer en cas d’augmentation générale des salaires, mais qui est la même pour tous les employés.{sidebar id=1}
Question 1
Ecrivez la classe des employés avec les informations utiles et des méthodes pour afficher les caractéristiques d’un employé et pour calculer son salaire.
Question 2
Certains employés ont des responsabilités hiérarchiques. Ils ont sous leurs ordres d’autres employés. Ecrivez une sous-classe des employés qui représente ces responsables en enregistrant leurs inférieurs hiérarchiques directs dans un tableau.
Ecrivez une méthode qui affiche les inférieurs directs (placés directement sous leurs ordres).
Question 3
Les commerciaux ont un salaire composé d’un fixe et d’un intéressement proportionnel à leurs ventes.
Ecrivez une sous-classe des commerciaux qui contient l’information sur leurs ventes du dernier mois, une méthode pour mettre à jour cette information et redéfinissez la méthode de calcul de leurs salaires.
Question 4
Ecrivez une classe représentant tout le personnel de l’entreprise, avec une méthode calculant la somme des salaires à verser.
Exercice JAVA opérateur infixé et postfixé
|
But:
|
Apprendre la différence entre un opérateur infixé et postfixé. | |||
|
Thème:
|
Opérateurs et expressions | |||
|
Fichiers:
|
Moyenne1.java, Moyenne2.java |
Compilez et exécutez les deux programmes Moyenne1.java et Moyenne2.java. Expliquez pourquoi la valeur retournée est différente d'un programme à l'autre.
|
Moyenne1.java
|
1 2 3 4 5 6 7 |
class Moyenne1{ public static void main(String[] args) { double noteProgrammation = 6.0; double noteAlgebre = 5.0; System.out.println("Ma moyenne est " + (noteProgrammation++ + noteAlgebre) / 2.0 ); } } |
|
Moyenne2.java
|
1 2 3 4 5 6 7 |
class Moyenne2{ public static void main(String[] args) { double noteProgrammation = 6.0; double noteAlgebre = 5.0; System.out.println("Ma moyenne est " + (++noteProgrammation + noteAlgebre) / 2.0 ); } } |
Dans le premier cas l'incrémentation se fait après l'évaluation de l'expression et dans l'autre avant.
TD de Programmation par objets et Java #4 : Les tableaux
Les tableaux
Exercice 2 : Programmation
Soit le programme Java suivant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class ProgBoolean { boolean a[]={true, false, true, false}; boolean b[]={true, true, false, false}; static void afficher(boolean[] x){ ... } static boolean[] non(boolean[] x){ ... } static boolean[] et(boolean[] x, boolean[] y) { ... } static boolean reduireEt(boolean[] x){ ... } public static void main(String[] args) { ... } } |
QUESTION1. Ecrire la méthode afficher qui prend un tableau de booléen et affiche son contenu de manière à ce que afficher(a) produise le résultat suivant: {vrai, faux, vrai, faux}Note: on fera attention aux blancs et aux espaces avant et après la virgule, et avant l'accolade.
2. Ecrire le code de la méthode non qui prend un tableau de booléen en argument et retourne un tableau de booléens inverses (opération logique 'non'). Donnez le résultat de afficher(non(a)).
3. Ecrire le code de la méthode et qui prend deux tableaux de booléens de même taille, effectue une opération de et logique sur chacun de ces éléments pris deux à deux et retourne un tableau de booléens contenant les résultats. On vérifiera que ces deux tableaux ont bien la même taille et on affichera un message d'erreur dans le cas contraire. Mathématiquement, le résultat ri = xi et yi, "i compris entre 0 et le nombre d'élément des tableaux x et y. Donnez le résultat de afficher(et(a,b)) et celui de afficher(non(et(a,b))).
Ecrire le code de la méthode reduireEt qui prend un tableau de booléen x et retourne un booléen qui est le et logique de tous les éléments de x. Mathématiquement, le résultat r de cette méthode est égal à x1 & x2 &.. & xn où n est le nombre d'éléments du tableau et '&' représente l'opération logique et.
J. Ferber
Exercices JAVA : terminologie, Structure, typage et conversion de type,Opérateurs relationnels
Exercice 1 : terminologie
Soit le morceau de code Java suivant : (x * 3) + 1
• quel nom donne-t-on `a ce morceau de code tout entier ?
• quels sont les opérateurs ?
• quels sont les opérandes de * ?
• quels sont les opérandes de + ?
• quel genre de chose est x dans ce morceau de code ?
• quel(s) type(s) a ou peut éventuellement avoir x ?
• quel est le type de 3 et 1 ?
• quel est le type de (x * 3) + 1 ?
• quelle est la valeur de (x * 3) + 1 ?
Exercice 2 : typage et conversion de type
Nous donnons ci-dessous des expressions avec le cas échéant les déclarations qui permettent de préciser leur sens.
Pour chacune de ces expressions, dˆ?tes si elle est correctement typée ou non. Si elle est correcte, donnez son type et sa
valeur. Notez bien qu’une expression incorrectement typée n’a ni type ni valeur. Elle n’a pas de sens.
1. 37.6 + 15
2. char c = ’a’;
c != ’d’;
3. char c = ’a’;
c + true;
4. char c = ’a’;
’c’ != c;
5. double x = 12.6;
(x + 5.6) < 12;
6. double x = 12.6;
(x + 5.6) < true;
7. double x = 12.6;
char c = ’a’;
(x < 15.0) && (c < ’z’);
8. double x = 12.6;
(x < 15.0) == true;
9. double x = 12.6;
char c = ’a’;
(x < 15.0) <= (c < ’z’);
Exercice 3 : structure d’un programme
Dans le programme suivant , dire quelles sont les les declarations, les appels de methode et les affectations :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Td1 { public static void main ( String [ ] arguments ) { Terminal.ecrireStringln ( ‘ ‘ exo1 ’ ’ ) ; int n=2 ; char c ; boolean b ; Terminal.ecrireDoubleln (3.0+2) ; n =3+2; n = n+n ; i n t m; m= n + ( 2 * ( n + 2 ) ) ; Terminal.ecrireIntln (m) ; Terminal.ecrireIntln(n) ; } } |
Exercice 2.4 : exemples du cours
Pour chaque programme, déterminez le résultat de son exécution. Opérateurs booléans
Tous les opérateurs booléans sont binaires, sauf l’opérateur de négation ! qui est unaire. Le résultat d’une expression
booléenne est un booléan.
– && (de conjonction, “et”) ,
– || (de disjonction, “or”), et
– ! (n´egation, “non”)
1 2 3 4 5 6 7 8 9 |
class Test 2 { public static void main ( String [ ] arg v ){ Terminal.ecrireBooleanln(true && false ) ; boolean a = true ; boolean b = true ; boolean c = true ; Terminal.ecrireBooleanln (!a | | ( b && c ) ) ; } } |
Opérateurs relationnels (de comparaison)
Permettent de comparer deux valeurs ou expressions toutes les deux de de type numérique ou char et renvoient
une valeur booléenne en résultat.
== égalité. Renvoie true si les deux valeurs comparées sont égales, false sinon.
Exemple : 1==4 renvoie false, ’a’==’a’ renvoie true < est plus petit. Renvoie true si la premi`ere valeur est strictement plus petite que la deuxieme, false sinon.
Exemple : 1<4 renvoie true, ’a’ < ’b’ renvoie true (ordre entre caract`eres ascii).
Programmation objet et Java Questionnaire
Question 1.
On considère l'instruction essai(); qui est l'appel d'une méthode d'objet. Qu'est-ce qui est vrai ?
- (a) l'instruction est invalide si on n'utilise pas
this.
- ;
- (b) elle est toujours valide;
- (c) elle est valide si elle apparaît dans une méthode d'objet de la même classe,
- (d) elle est invalide parce qu'elle est sans argument,
- (e) elle n'est pas valide parce qu'il n'y a pas d'objet appelant.
Question 2. Quelles sont les affirmations vraies parmi les suivantes ?
(a) une classe peut contenir à la fois des méthodes statiques et des méthodes d'objets,
(b) seules des classes sans attributs peuvent contenir des méthodes statiques,
(c) seules des classes utilisateur peuvent contenir des méthodes statiques
(d) Si une classe contient des méthodes statiques, elle ne peut contenir des méthodes d'objet.
Question 3. Une méthode publique statique peut toujours être appelée en préfixant l'appel
(a) du nom de la classe
(b) du nom d'un objet de la classe
(c) this
(d) sans préfixe.
Question 4. Une classe Exemple a les deux constructeurs
Exemple(int a)
Exemple(float f, char c)
Qu'elles sont les déclaration correctes parmi les suivantes ?
(a) Exemple e = new Exemple();
(b) Exemple e = new Exemple(7);
(c) Exemple e = new Exemple(3.1,'A');
(d) Exemple e = new Exemple(7, 'a');
Question 5. Une méthode qui lève une exception en utilisant throw doit contenir une bloc catch pour traiter cette exception.
(a) vrai,
(b) faux.
Question 6. On suppose que Beta dérive de Alpha et Gamma dérive de Beta. Dans un appel d'une méthode de profil void methode(Object p) l'argument passé à methode peut être
(a) de type Alpha, Beta, Gamma ou Object,
(b) Objectet Alpha seulement,
(c) Gamma et Beta seulement.
Question 7. On considère le programme que voici:
class Exemple {
public boolean b = true;
public boolean set(boolean x) {
x = !x ;
return (x == b);
}
public static void main(String[] args) {
Exemple ex = new Exemple();
ex.b = ex.set(ex.b);
System.out.println(ex.b);
}
}
(a) le programme imprime true.
(b) le programme imprime false.
Question 8. On considère le programme suivant:
class Point {
int x, y;
public Point(int xx, int yy) { x = xx; y = yy; }
public void change(Point p) { p.x += x; p.y += y; }public static void main(String[] args) {
Point a = new Point(2, 3), b = new Point(5, 10);
a.change(b);
}
}
Quel est le résultat ?
(a) a et b sont inchangés.
(b) seul a est changé
(c) seul b est changé
(d) a et b sont changés.
Question 9. Une classe Beta dérive d'une classe Alpha. Les deux classes ont une méthode public boolean estIl(). On considère le fragment de programme
Beta b = new Beta();
Alpha a = b;
if ( a.estIl() ) ...
Qu'est-ce qui est vrai ?
(a) la méthode de la classe Alpha est appelée parce que Java utilise la liaison dynamique
(b) la méthode de la classe Beta est appelée parce que Java utilise la liaison dynamique
(c) la méthode de la classe Alpha est appelée parce que a est de type Alpha
(d) l'appel n'est pas valable parce que le compilateur ne sait pas déterminer laquelle des méthodes appeler.
Question 10. On considère la classe suivante.
public class X {
int x = 10;
public X() { x = 20; }
public int getX() { return x; }
}
Que se passe-t-il avec l'instruction que voici:
System.out.println( new X().getX() );
(a) Ne compile pas
(b) Compile mais lève une exception à l'exécution
(c) Affiche 10
(d) Affiche 20
(e) Boucle indéfinimen
TD de Programmation par objets et Java #3 : Les association entre les Objets
Les associations entre objets
Exercice 1: variation sur le compte en banque
On donne les classes Compte et Personne suivantes :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Compte { int numero; int solde; Personne client; void deposer(int s){ solde = solde + s; } void retirer (int s){ solde = solde - s; } int avoirSolde() { return(solde); } void associerPersonne(Personne p){ client = p; p.ajouterCompte(this); } } class Personne { String nom; String prenom; Compte monCompte; void ajouterCompte(Compte c){ monCompte = c; } Personne(String m, String p, int a){ nom = m; prenom = p; annee = a; } } |
Définir un constructeur de la forme:
Compte(int n, String m, String p, int a) où n représente le numéro du compte, m le nom du client, p son prénom et a son
année de naissance.
Ce constructeur doit créer une personne et mettre à jour les liens entre le client du compte et le compte lui-même.
Exercice 2: L'arbre généalogique
On désire réaliser un système permettant de construire et d'afficher un arbre généalogique.
Question A
a) Créer la classe Date qui contient une date sous la forme de 3 entiers, le jour, le mois et l'année.
b) Définir un constructeur de la forme Date(int j, int m, int a) qui sert à construire une telle date.
c) Définir une méthode versChaine() qui retourne une chaîne de caractère, représentation de la date sous la forme jour/mois/année.
Exemple:
Date d = new Date(20, 10, 1999);
System.out.println(d.versChaine()); // affiche: 20/10/1999
Question B
a) Définir la classe Personne qui est telle que toute personne est définie par son nom, son prénom, sa date de naissance et éventuellement par son père, sa mère (qui sont tous deux des personnes) et par sa date de décès.
b) Faire un constructeur qui permet de créer une personne à partir de son nom, son prénom, le jour, le mois et l'année de sa date de naissance.
c) Faire des méthodes d'accès pour la définition du pere, de la mere et de l'année de décès de la personne. Voilà ce que cela donne:
Personne jean = new Personne("Dupond", "Jean", 3, 1, 1966);
Personne marie = new Personne("Durand", "Marie", 5, 9, 1942);
Personne marcel = new Personne("Dupond", "Marcel", 15, 10, 1938);
Personne helene = new Personne("Leblanc", "Hélène", 21, 11, 1908);
Personne paul = new Personne("Durand", "Paul", 12, 06, 1905);
helene.deces(10,08,1986);
paul.deces(1,12,1970);
jean.pere(marcel); // Jean a comme pere Marcel
jean.mere(Marie);
marie.pere(Paul);
marie.mere(Helene);
d) Faire une méthode afficher() dans Personne qui donne le résultat suivant:
jean.afficher()
Jean Dupond
né(e) le 3/1/1996
helene.afficher()
Hélène Leblanc
né(e) le 21/11/1908
décédé(e) le 10/08/1986
e) Faire une méthode afficherGenealogie() dans Personne affiche toute la généalogie d'une personne. Exemple:
jean.afficherGenealogie();
Jean Dupond
né(e) le 3/1/1996
a comme père:
Marcel Dupond
né(e) le 15/10/1938
a comme mère:
Marie Durand
né(e) le 5/9/1942
a comme père:
Paul Durand
né(e) le 5/9/1942
décédé(e) le 1/12/1970
a comme mère
Hélène Leblanc
né(e) le 21/11/1908
décédé(e) le 10/08/1986
Note: dans un premier temps on ne s'intéressera pas à l'indentation. Mais dansun deuxième temps on se posera la question de l'indentation. Idée: créer une méthode auxiliaire (que l'on appellera afficherGenealogie1(int i) où i est le nombre de blanc qui sont affichées avant les message de sortie, et créer de même une méthode auxiliaire afficher1(int i) qui fait comme afficher mais qui place i blanc avant le message de sortie.
J. Ferber
Exercice java sur les conversions entre les types de base entiers et doubles
|
But:
|
Apprendre quelles conversions on peut faire entre entiers et doubles. | |||
|
Thème:
|
Types de base | |||
|
Fichiers:
|
Transtypage.java |
Indiquez, pour chaque affectation dans le programme Transtypage ci-dessous, si l'affectation est possible et, le cas échéant, la valeur exacte qui sera affectée à la variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Transtypage { public static void main(String[] args) { int n1 = 2; double r1 = 2.7; int n2 = 2.7; double r2 = 5; int n3 = (int) 5.6; double r3 = 5.6; int n4 = 9; double r4 = (double) n4; double r5 = (int) r4; int n5 = 19 / 4; double r6 = 5.0; int n6 = n5 / r5; int n7 = (int) (n5 / r5); double r7 = 19.0 / r6; double r8 = 15.0 / n3; double r9 = 19 / 4; double r10 = (double) (19 / 4); double r11 = (double) 19 / (double) 4; } } |
n1 vaut 2
r1 vaut 2.7
n2 vaut (affectation impossible)
r2 vaut 5.0
n3 vaut 5
r3 vaut 5.6
n4 vaut 9
r4 vaut 9.0
r5 vaut 9.0
n5 vaut 4
n6 vaut (affectation impossible)
r6 vaut 5.0
n7 vaut 0
r7 vaut 3.8
r8 vaut 3.0
r9 vaut 4.0
r10 vaut 4.0
r11 vaut 4.75
Exercice JAVA modularisation et portée d'une variable
|
But:
|
Illustrer un point important concernant la portée des variables | |||
|
Thème:
|
Modularisation, portée | |||
Le programme Portee.java ci-dessous sert à illustrer un point important qui concerne la portée des variables dans un programme. Sans exécuter le programme, indiquez tout ce que le programme affichera à l'écran lors de l'exécution. Exécutez ensuite le programme (en cliquant ci-dessous sur "Exécutez le programme") pour vérifier votre réponse.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
class Portee { public static void main(String[] args) { int x = 11, y = 22; System.out.println("1. x = " + x); System.out.println("2. y = " + y); System.out.println(); calculer1(x, y); System.out.println("5. x = " + x); System.out.println("6. y = " + y); System.out.println(); calculer2(x, y); System.out.println("11. x = " + x); System.out.println("12. y = " + y); System.out.println(); int [] object = {5}; System.out.println("13. object [0] = " + object [0]); calculer3(object); System.out.println("15. object [0] = " + object [0]); } static void calculer1(int x, int y) { x = 878; y++; System.out.println("3. x = " + x); System.out.println("4. y = " + y); } static void calculer2(int a, int b) { int x = 33; int y = 44; a = 2 * x; b = 2 * y; System.out.println("7. x = " + x); System.out.println("8. y = " + y); System.out.println("9. a = " + a); System.out.println("10. b = " + b); } static void calculer3(int [] object) { object [0] = 37; System.out.println("14. object [0] = " + object [0]); } } |
Le programme illustre le fait que chaque variable est locale au bloc où elle a été déclarée. Cela veut dire que la portée (en anglais scope) de la variable est limitée à ce bloc et que la variable n'est pas visible ou utilisable ailleurs dans le programme. Notamment les variables déclarées dans une méthode sont locales à la méthode en question et ne peuvent pas être accédées depuis d'autres méthodes. Pour communiquer une valeur d'une méthode à une autre, il faut l'envoyer comme argument dans l'appel.
Exécution du programme Portee:
1. x = 11 2. y = 22 3. x = 878 4. y = 23 5. x = 11 6. y = 22 7. x = 33 8. y = 44 9. a = 66 10. b = 88 11. x = 11 12. y = 22 13. object [0] = 5 14. object [0] = 37 15. object [0] = 37
Exercice Java : Programme de gestion de ligne d'autocar
Exercice 1 : prix des billets d’autocar
Dans cet exercice, on veut gérer une ligne de car qui relie Vierzon à Orléans en passant par Salbris, Nouans, Lamotte-Beuvron et La Ferté Saint-Aubin. Chaque tronçon du trajet a un certain prix et le prix d’un billet est la somme des prix des tronçons qu’il comporte.
La ligne fonctionne dans les deux sens, le prix est identique dans les deux sens.
Dans cet exercice, on ne veut utiliser que des tableaux, pas d’enregistrement.
On va stocker dans un tableau les noms des villes, en les mettant dans l’ordre dans lequel elles sont desservies (l’ordre donné ci-dessus). Dans un autre tableau, on va stocker les prix des différents tronçons.
Ces prix sont les suivants :
| départ | arrivée | prix |
|
Vierzon Salbris Nouans Lamotte-Beuvron La Ferté Saint-Aubin |
Salbris Nouans Lamotte-Beuvron La Ferté Saint-Aubin Orléans |
3.20 1.80 2.30 4.20 5.00 |
Avant de commencer à programmer, dessinez les deux tableaux sur papier et réfléchissez aux algorithmes permettant de répondre aux différentes questions. {sidebar id=1}
1. écrivez une méthode permettant de retrouver l’indice d’une ville dont on donne le nom en paramètre (c’est à dire sa position dans le premier tableau).
2. écrivez une méthode qui calcule le prix d’un trajet étant donnés les noms des villes de départ et d’arrivée
Question 2
On veut instaurer des tarifs dégressifs selon le nombre de tronçons parcourus : le premier tronçon est payé à plein tarif, le second avec 10% de réduction, le second avec 20%, etc. Ecrivez une méthode qui réalise le calcul du prix d’un trajet selon ce principe.
Question 3
On veut généraliser le système pour un ensemble de lignes de bus : que faut-il changer dans le programme?
Vous écrirez un programme avec deux lignes de bus et un seul programme qui calcule les prix des trajets. Les billets sont pour un trajet sur une ligne donnée, on ne fait pas de billet avec correspondance
Exercice 2 : distances entre villes
On s’intéresse aux distances entre deux villes situées le long d’une même route. Comme exemple, on prend la nationale 20 entre Orléans et Vierzon. Voici le tableau des distances :
| départ | arrivée | distance |
|
Orléans La Ferté Saint-Aubin Lamotte-Beuvron Nouans Salbris |
La Ferté Saint-Aubin Lamotte-Beuvron Nouans Salbris Vierzon |
21 Km 14 Km 8 Km 13 Km 23 Km |
1. représentez le tableau ci-dessus en java au moyen d’un premier tableau enregistrant les noms de ville et d’un second enregistrant les distances.
2. écrivez un programme qui calcule la distance entre deux villes.
3. écrivez un programme qui calcule un tableau à deux dimensions en registrant toutes les distances entre deux villes.
Question 2 {sidebar id=8}
On veut réaliser la même chose, mais avec plusieurs routes, si bien qu’il peut y avoir plusieurs routes pour aller d’une ville à un autre. Dans ce cas, on veut calculer et enregistrer dans le tableau à deux dimensions la distance la plus courte.
Les données du calculs seront les tronçons de route qui relient directement deux villes, c’est-à-dire qui vont d’une ville à l’autre sans passer par aucune autre ville. Pour chaque tronçon, on doit donner sa distance.
Comment peut-on représenter ces données en Java ? Comment peut-on calculer la distance la plus petite entre deux villes ? Attention, il faut éviter que le calcul proposé ne produise des boucles infinies (par exemple en refaisant éternellement certains trajets).
Cette question est une question de réflexion à laquelle vous pouvez répondre sans écrire de programme. Vous pouvez également écrire le programme si vous le désirez.
Exercice portée d'une variable
|
But:
|
Illustrer un point important concernant la portée des variables | |||
|
Thème:
|
Modularisation, portée | |||
|
Fichiers:
|
Le programme Portee.java ci-dessous sert à illustrer un point important qui concerne la portée des variables dans un programme. Sans exécuter le programme, indiquez tout ce que le programme affichera à l'écran lors de l'exécution. Exécutez ensuite le programme (en cliquant ci-dessous sur "Exécutez le programme") pour vérifier votre réponse.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class Portee { public static void main(String[] args) { int x = 11, y = 22; System.out.println("1. x = " + x); System.out.println("2. y = " + y); System.out.println(); calculer1(x, y); System.out.println("5. x = " + x); System.out.println("6. y = " + y); System.out.println(); calculer2(x, y); System.out.println("11. x = " + x); System.out.println("12. y = " + y); System.out.println(); int [] object = {5}; System.out.println("13. object [0] = " + object [0]); calculer3(object); System.out.println("15. object [0] = " + object [0]); } static void calculer1(int x, int y) { x = 878; y++; System.out.println("3. x = " + x); System.out.println("4. y = " + y); } static void calculer2(int a, int b) { int x = 33; int y = 44; a = 2 * x; b = 2 * y; System.out.println("7. x = " + x); System.out.println("8. y = " + y); System.out.println("9. a = " + a); System.out.println("10. b = " + b); } static void calculer3(int [] object) { object [0] = 37; System.out.println("14. object [0] = " + object [0]); } } |
Le programme illustre le fait que chaque variable est locale au bloc où elle a été déclarée. Cela veut dire que la portée (en anglais scope) de la variable est limitée à ce bloc et que la variable n'est pas visible ou utilisable ailleurs dans le programme. Notamment les variables déclarées dans une méthode sont locales à la méthode en question et ne peuvent pas être accédées depuis d'autres méthodes. Pour communiquer une valeur d'une méthode à une autre, il faut l'envoyer comme argument dans l'appel.
Exécution du programme Portee:
1. x = 11 2. y = 22 3. x = 878 4. y = 23 5. x = 11 6. y = 22 7. x = 33 8. y = 44 9. a = 66 10. b = 88 11. x = 11 12. y = 22 13. object [0] = 5 14. object [0] = 37 15. object [0] = 37
Exercice langage Java POO- dessins - affichage - insertion entre éléments
Exercice 1 : dessins
On reprend ici la classe Liste du cours, que l’on rappelle. Pour chacun des points marqués par un commentaire dans la méthode main, dessinez la liste l. Vous utiliserez le même genre de dessins que ceux du cours. On reprend ici la classe Liste du cours, que l’on rappelle. {sidebar id=2}
1 |
public class ElementListe { |
Exercice 2 : affichage
| {sidebar id=1} |
Question 1
Reprendre la classe Liste du cours et lui ajouter une méthode ecrireListe qui affiche la liste.
Question 2
Réécrire la méthode ecrireListe en utilisant la récursivité (sans boucle).
Question 3
Si ce n’est pas déjà fait, faire afficher une virgule entre chaque valeur de la liste. Attention : il ne doit pas y avoir de virgule avant la première valeur ni après la dernière.
Exercice 3 : insertion entre chaque élément
Ajouter une méthode qui permette d 'insérer entre chaque élément de la liste une nouvelle valeur. Par exemple, avec la liste [5,12,7], la méthode insererEntre(1) donnerait : [5,1,12,1,7].
Exercice java POO - programme égalité d’objets
{sidebar id=6}
1 |
class Exo12_4{ |
| {sidebar id=1} |
Essayez de prédire le résultat de l’exécution de ce programme. Testez le programme. Que peut-on en déduire sur la notion d’égalité d’objets en java ?
Notez que l’expression c1.incremente().getValeur() comprend deux appels de méthodes successifs. D’abord la méthode incremente est appelée sur c1. Cette méthode renvoie un objet de type Compte qui est celui sur lequel la méthode est appelée (this). Sur cet objet, la méthode getValeur est appelée. Cela revient à appeler successivement les deux méthodes sur le même objet.
Exercice java orienté objet : classe, méthodes et constructeur - compte bancaire
Exercice 1 : Méthodes ,Tableau
Voici le texte d’une classe représentant de façon sommaire un compte bancaire et les opérations bancaires courantes {sidebar id=8}
1 |
class Compte { |
Question 1
Comment fonctionne la méthode virerVers ? Combien de comptes fait-elle intervenir ?
Question 2
Créez deux comptes que vous affecterez à deux variables. Ecrivez le code correspondant aux opérations suivantes :
– dépot de 500 euros sur le premier compte.
– dépot de 1000 euros sur le second compte.
– retrait de 10 euros sur le second compte.
– virement de 75 euros du premier compte vers le second.
– affichage des soldes des deux comptes.
Vous mettrez le code java correspondant à cette question dans la méthode main d’une nouvelle classe appelée TesteCompte. Vous compilerez et testerez ce programme.
Question 3
Créez un tableau de dix comptes. Pour cela, notez bien qu’il faut d’abord créer le tableau puis créer successivement les dix comptes à mettre dans les dix cases de ce tableau.
Dans chaque case, faites un dépot de 200 euros plus une somme égale à 100 fois l’indice du compte dans le tableau.
Ensuite, vous ferez un virement de 20 euros de chaque compte vers chacun des comptes qui le suivent dans le tableau (par exemple, du compte d’indice 5, il faut faire des virements vers les comptes d’indice 6,
7, 8 et 9).
Enfin, vous afficherez les soldes de tous les comptes.
Ici encore, vous testerez et compilerez le code proposé.
Exercice 2 : constructeurs
Cet exercice reprend la classe Compte de l’exercice 1. {sidebar id=1}
Question 1
Complétez la classe Compte avec une information supplémentaire : le nom du titulaire du compte (type String). Vous modifierez la méthode d’affichage pour qu’elle affiche cette information.
Question 2
Créez un constructeur pour la classe Compte. Ce constructeur doit prendre en paramètre le nom du titulaire du compte.
Donnez le code de création d’un compte qui appelle ce constructeur.
Question 3
Faut-il prévoir des méthodes permettant de changer le nom du titulaire du compte ?
Exercice 3 : méthodes statiques ou non
Parmi les méthodes de la classe suivante, lesquelles peuvent être statiques et lesquelles ne peuvent en aucun cas être statiques ?
1 |
class Exo12_3{ |
TP Java POO : programme Hôpital
On reprend le code donné pour l’exemple de réalisations des statistiques dans un hôpital. On aimerait compléter les classe Hopital, Chambre et Patient avec des fonctionnalités nouvelles. Méthodologie : pour chaque méthode ajoutée, vous ajouterez des tests de cette méthode dans le programme main afin de vous assurer qu’elle fonctionne correctement.
Question 1
Exécutez la méthode main fournie dans ce code. Modifiez ce programme afin d’ajouter un patient dans une chambre choisie par vous et où il reste de la place. Effectuez des affichages afin de vérifier que le patient a été bien ajouté. Faîtes de même avec un patient et une chambre où il n’y a plus de place. Comment se comporte le programme ?
Question 2
Ajoutez des méthodes dans les classes appropriées permettant d’afficher toutes les chambres avec de la place en indiquant à chaque fois le nombre de places libres dans chacune. Ajoutez des tests de cette méthode dans le main.
Question 3
Ajoutez une méthode afin de saisir les données d’un patient. Cette méthode doit retourner un patient en résultat. Quelle est son entête ? S’agit-il d’une méthode statique ou dynamique ? Dans quelle classe la placez vous ?
Question 4
Modifiez le main afin de proposer (en boucle) 4 options à l’utilisateur : afficher toutes les chambres où il reste de la place ; saisir les données d’un patient et l’ajouter dans une chambre donnée ; saisir les données d’un patient et l’ajouter dans une des chambres les plus remplies ; quitter.
Question 5
Ajoutez des méthodes dans les classes appropriées permettant de trouver le numéro de chambre où se trouve un patient, donné par son nom, ou signaler son absence s’il n’est pas trouvé.
Question 6
Ajoutez des méthodes dans les classes appropriées permettant de sortie d’un patient donné par son nom, ou signaler son absence s’il n’est pas trouvé. Vous devrez vous assurer que le nombre de lits occupés, de chambres vides et de chambres pleines sont correctement mis à jour après une sortie.
Question 7
Ajoutez un constructeur dans la classe Hopital permettant de construire un hôpital ayant un nombre de list différent par chambre. On suppose que seulement des chambres de 1, 2, 3 ou 4 lits sont possibles. Faut-il changer d’autres méthodes suite à ce changement ?
Question 8
On souhaite ajouter une date d’entrée et une date de sortie pour chaque patient, ainsi qu’un prix de la nuit dans chaque chambre. Onconsidère que ce prix est le même pour toutes les chambres. Lors de la sortie d’un patient, on souhaite calculer et afficher le montant à régler pour son séjour. Quelles sont les modifications que vous devez réaliser et dans quelles classes ?
Exercice java machine de Turing : algorithme et POO de base
|
But:
|
Le but est d'écrire un programme permettant de simuler une machine de Turing. | |||
|
Thème:
|
algorithme, POO de base |
Le but est d'écrire un programme Turing.java permettant de simuler une machine de Turing.
Proposition de méthode :
- Définissez un certain nombre de constantes utiles accessibles par toutes vos classes:
char EPSILON='e';
int POSITION_INITIALE=0;
int UNDEF=0;
int ETAT_INITIAL=1; - Pour simuler une bande de longueur infinie, vous pouvez utiliser une String :
- lorsque l'on cherchera à déplacer la tête au-delà du dernier élément, il suffira de créer un élément supplémentaire, initialisé avec le symbole epsilon (représenté par le caractère 'e').
- lorsque l'on cherchera à déplacer la tête avant le premier élément, il suffira d'insérer en début de chaine le symbole epsilon
- La tête de lecture sera représentée simplement par une classe d'objets ayant pour attribut un entier , indiquant sa position courante. A cette classe d'objet seront associées les méthodes permettant d'avancer et de reculer la tête de lecture (i.e. incrémenter/décrémenter sa position).
- Pour représenter la table de transitions, vous utiliserez un tableau à deux dimensions. Ce tableau aura trois colonnes (une par valeur possible du caractère courant ([ 0, 1, epsilon]));
- chaque 'case' définissant une transition est un objet de type Transition
class Transition {
private int etat;
private char caractere;
private int deplacement;
} -
Écrivez une classe TMachine, simulant une machine de Turing.
Vous aurez besoin des attributs suivants :
- un entier (ou un type prédéfini par vous) modélisant l'état actuel de la machine
- une bande
- une tête de lecture
- une table de transitions
- Définissez les méthodes suivantes :
- un constructeur permettant de créer une machine de Turing
TMachine(final Transition[][] table). Ce constructeur devra également mettre l'état actuel à ETAT_INITIAL, la bande à la chaine vide et la tête de lecture à POSITION_INITIALE - une méthode permettant de ré-initialiser la machine (pour recommencer avec une nouvelle entrée)
void reinitialise(final String entree). L'état actuel sera remis à ETAT_INITIAL, la bande initialisée au moyen de entree et la tête de lecture sera remise à POSITION_INITIALE - les méthodes implémentant les primitives de lecture et d'écriture de la bande :
char lecture(); lit le caractère 'courant' de la bande
void ecriture(char c); remplace dans la bande le caractère courant par la valeur transmise en argument
Notez que, dans l'implémentation proposée, lecture et ecriture peuvent changer la valeur de tete : on simulera ainsi le fait que la bande est infinie, en insérant le bon nombre d'epsilons en début de bande lorsque la position de la tête est négative (naturellement, lorsque les espilons auront étés insérés, on devra repositionner la tête à zéro). [on aurait également pu choisir d'effectuer ces opérations - simuler une bande infinie - lors des déplacements de la tête...]
- une méthode permettant de démarrer la simulation de la machine.
Choisissez une convention sur la valeur de l'état pour stopper la machine (par exemple, une valeur négative). - une méthode permettant d'afficher l'etat de la machine de Turing selon l'exemple d'exécution donné ci-dessous.
- un constructeur permettant de créer une machine de Turing
Application 1: Test de Parité
Testez votre machine avec l'exemple du cours testant la parité de l'entrée.
Avec la modélisation proposée, utilisez la syntaxe suivante pour définir une table de transition (utilisée par le constructeur de TMachine):
Transition[][] table1 = {
|
La constante UNDEF représente un état non défini également utilisé pour "l'ordre de fin d'exécution".
Dans cet exemple, on suppose que le déplacement vers l'avant est représenté par la valeur +1, et le déplacement vers l'arrière par -1.
Exemple (détaillé) d'exécution :
Lancement de la machine de Turing
--------------------------------
Etat actuel : 1
Bande :
10
^ (Tete : 0)
--------------------------------
lu : 1, nouvel état : 1, écrit : 1, avance
--------------------------------
Etat actuel : 1
Bande :
10
^ (Tete : 1)
--------------------------------
lu : 0, nouvel état : 1, écrit : 0, avance
--------------------------------
Etat actuel : 1
Bande :
10
^ (Tete : 2)
--------------------------------
lu : e, nouvel état : 2, écrit : e, recule
--------------------------------
Etat actuel : 2
Bande :
10e
^ (Tete : 1)
--------------------------------
lu : 0, nouvel état : 3, écrit : e, recule
--------------------------------
Etat actuel : 3
Bande :
1ee
^ (Tete : 0)
--------------------------------
lu : 1, nouvel état : 3, écrit : e, recule
--------------------------------
Etat actuel : 3
Bande :
eee
^ (Tete : -1)
--------------------------------
lu : e, nouvel état : 5, écrit : 1, avance
--------------------------------
Etat actuel : 5
Bande :
1eee
^ (Tete : 1)
--------------------------------
lu : e, nouvel état : 0, écrit : e, recule
--------------------------------
Etat actuel : 0
Bande :
1eee
^ (Tete : 0)
--------------------------------
Arrêt de la machine de Turing.
Application 2: Inversion de séquence sur une Machine de Turing
Écrivez (sur papier) la table de transition d'une machine de Turing réalisant l'inversion d'une séquence de bits.
Par exemple, si l'on a 1101 en entrée, on devra avoir 1011 en sortie.
On supposera que:
- la bande de longueur infinie ne contient rien d'autre que la séquence, ce qui signifie qu'à l'exception de la séquence, tous les caractères sont des epsilon )(donc la séquence est délimitée par des epsilon);
- la tête de lecture/écriture est initialement positionnée sur le premier caractère de la séquence.
Remarquez bien qu'il n'est pas nécessaire que la séquence inversée occupe, sur la bande, la même position que la séquence initiale.
Testez votre machine sur un exemple simple (du moins dans un premier temps) !
Indications: si vous êtes en panne d'inspiration, vous pouvez essayer l'algorithme proposé ci-après.
- Si la séquence d'entrée est vide, terminer. Sinon, aller jusqu'à la cellule immédiatement à droite de la frontière droite de la séquence, en mémorisant (dans la valeur des états : voir l'algorithme de parité ci-dessus) la valeur du dernier élément de la séquence.
- Si la (nouvelle) séquence n'est pas vide, aller tout d'abord à sa frontière droite (toujours en mémorisant le dernier élément), puis écrire l'élément mémorisé (qui est alors le dernier élément de la nouvelle séquence), se déplacer à la fin de la séquence d'entrée courante, effacer son dernier élément et se déplacer à gauche. (Si la séquence n'est pas vide, on est alors de nouveau sur le dernier élément de la séquence d'entrée 'courante')
- Si la séquence d'entrée courante est vide, aller à la frontière gauche de la nouvelle séquence et terminer. Sinon, aller au début de la nouvelle séquence en mémorisant le dernier caractère de la séquence d'entrée courante, puis recommencer en (2)
|
Fichiers:
|
Turing.java |
1 |
// ---------------------------------------------------------------------- |
Exercice transformer un programme java donné en un programme orienté objet- taxes
|
But:
|
Transformer un programme donné en un programme OO | |||
|
Thème:
|
Transformation d'un programme non OO en un programme OO, POO de base |
Le fichier Taxes1.java contient un programme qui aide une entreprise à stocker des données sur sa flotte de voitures et de calculer la taxe annuelle totale à payer pour la flotte. Le programme est modularisé sous forme de méthodes auxiliaires. Copiez le programme sous le nom de Taxes2.java et transformez-le en programme orienté objets. Dans ce but, vous pouvez vous inspirer de l'exemple vu en cours. Suivez les étapes suivantes:
- Etudiez le fonctionnement du programme. L'entreprise a une flotte de voitures composée d'une Toyota de cylindrée 1598 et d'une BMW de cylindrée 2756 dont les données sont stockées dans des variables de type int et String. La méthode auxiliaire afficherVoiture() aide la méthode main à afficher les données sur la flotte. Les 3 méthodes auxiliaires afficherTaxeFlotte(),
calculerTaxeFlotte() et calculerTaxeVoiture() s'occupent de calculer et d'afficher la taxe à payer pour la flotte. La taxe varie entre 300 et 700 francs par voiture et dépend de sa cylindrée. - Ajoutez une classe Voiture qui regroupera tout ce qui concerne un objet de type voiture, comme par exemple les variables contenant la marque et la cylindrée, la méthode pour afficher les données d'une voiture et la méthode pour calculer la taxe d'une voiture. Les méthodes d'instance dans le nouveau programme auront typiquement moins de paramètres que les méthodes auxiliaires correspondantes dans l'ancien programme. N'oubliez pas qu'une méthode d'instance n'a pas de mot-clé static. Ajoutez une méthode constructeur à la classe et le mot-clé private pour les variables et les méthodes d'instance qui ne seront pas utilisées à l'extérieur de la classe.
- Ajoutez une classe Flotte qui regroupera tout ce qui concerne un objet de type flotte, e.g. les variables pour les voitures, la méthode pour afficher les données d'une flotte et la méthode pour calculer la taxe d'une flotte. Ces méthodes appelleront typiquement les méthodes de la classe Voiture.
- Modifiez la méthode main. Idéalement, elle n'aura que 3 instructions: construction d'un objet de type Flotte, appel à une méthode d'instance pour afficher les informations sur la flotte et appel à une méthode d'instance pour calculer et afficher la taxe totale de la flotte.
Exemple d'exécution du programme:
Vous avez une Toyota de cylindrée 1598
Vous avez une BMW de cylindrée 2756
Taxe totale à payer: 1000.0 francs
Code donné:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/* Ce programme est modularisé sous forme de méthodes auxiliaires. Il vous est demandé de le transformer en un programme orienté objets. */ class Taxes1 { public static void main(String[] args) { // Données pour la première voiture (marque et cylindrée): String marque1 = "Toyota"; int cylindree1 = 1598; // Données pour la deuxième voiture (marque et cylindrée): String marque2 = "BMW"; int cylindree2 = 2756; // Affichage de la flotte: afficherVoiture(marque1, cylindree1); afficherVoiture(marque2, cylindree2); // Calcul et affichage de la totalité des taxes: afficherTaxeFlotte(cylindree1, cylindree2); } static void afficherVoiture(String marque, int cylindree) { // Cette méthode affiche les données d'une voiture * System.out.println("Vous avez une " + marque + " de cylindrée " + cylindree); } static void afficherTaxeFlotte(double cylindree1, double cylindree2) { // Cette méthode calcule et affiche la taxe totale des deux // voitures double taxe = calculerTaxeFlotte(cylindree1, cylindree2); System.out.println("Taxe totale à payer: " + taxe + " francs"); } static double calculerTaxeFlotte(double cylindree1, double cylindree2) { // Cette méthode calcule la taxe totale pour deux voitures double taxe1 = calculerTaxeVoiture(cylindree1); double taxe2 = calculerTaxeVoiture(cylindree2); return (taxe1 + taxe2); } static double calculerTaxeVoiture(double cylindree) { // Cette méthode retourne la taxe à payer pour une voiture de la // cylindrée indiquée * double taxe; if (cylindree <= 1600) taxe = 300.0; else if (cylindree <= 2300) taxe = 500.0; else taxe = 700.0; return taxe; } } |
|
Fichiers:
|
Le code complet du corrigé vous est fourni ci-dessous. A remarquer en particulier:
- Les méthodes propres à un type d'objet sont mises dans la classe décrivant ce type d'objet (encapsulation). Exemple: calculerTaxeFlotte est mise dans la classe Flotte (et porte désormais le nom calculerTaxe, voir point suivant).
- Les concepts OO nous permettent la réutilisation d'identifiateurs parlants pour les noms de méthodes. Par exemple, il n'est plus nécessaire d'avoir pour les affichages ou le calcul de taxes deux noms de méthodes distincts: afficherFlotte et afficherVoiture ou calculerTaxeFlotte et calculerTaxeVoiture . Ces méthodes peuvent désormais simplement s'appeller afficher (resp. calculerTaxe) sans aucun risque de confusion puisque chaque classe a ses propres attributs et méthodes.
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
/* Version orientée objets de Taxes1 */ class Taxes2 { public static void main(String[] args) { // Construire 1 objet de type Flotte: Flotte f = new Flotte("Toyota", 1598, "BMW", 2756); // Afficher la flotte: f.afficher(); // Calculer et afficher la taxe de la flotte: f.afficherTaxe(); } } class Flotte { // Variables d'instance de la classe Flotte: private Voiture v1; private Voiture v2; // Méthode constructeur: public Flotte(String marque1, int cylindree1, String marque2, int cylindree2) { // Construire 2 objets de type Voiture: v1 = new Voiture(marque1, cylindree1); v2 = new Voiture(marque2, cylindree2); } public void afficher() { // Cette méthode affiche les données de toutes les voitures de la // flotte en appelant la méthode afficher de chaque objet voiture v1.afficher(); v2.afficher(); } public void afficherTaxe() { // Cette méthode calcule et affiche la taxe totale double taxe = calculerTaxe(); System.out.println("Taxe totale à payer: " + taxe + " francs"); } private double calculerTaxe() { // Cette méthode calcule la taxe totale pour les deux // voitures. Elle est privée car il n'y a aucune raison de // l'appeler depuis l'extérieur de la classe. return (v1.calculerTaxe() + v2.calculerTaxe()); } } class Voiture { // Variables d'instance de la classe Voiture: private String marque; private int cylindree; // Méthode constructeur: public Voiture(String marque, int cylindree) { this.marque = marque; this.cylindree = cylindree; } public void afficher() { // Cette méthode affiche les données d'une voiture System.out.println("Vous avez une " + marque + " de cylindrée " + cylindree); } public double calculerTaxe() { // Cette méthode retourne la taxe à payer pour l'objet // double taxe; if (cylindree <= 1600) taxe = 300.0; else if (cylindree <= 2300) taxe = 500.0; else taxe = 700.0; return taxe; } }
Exercice java transformer un programme donné en un programme orienté objet - Banques
|
But:
|
Transformer un programme donné en un programme OO | |||
|
Thème:
|
Transformation d'un programme non OO en un programme OO, POO de base |
Le fichier Banque1.java contient un programme bancaire qui est modularisé sous forme de méthodes auxiliaires. Transformez-le en programme orienté objet sous le nom de Banque2.java en suivant les étapes suivantes :
- Etudiez le fonctionnement du programme. La banque a 2 clients. Chaque client a un compte privé et un compte d'épargne avec des soldes différents. Le taux d'intérêt d'un compte d'épargne est plus élevé que celui d'un compte privé. Les données de chaque client (nom, ville et soldes) sont affichées avant et après le bouclement des comptes.
- Réfléchissez aux objets que vous aimeriez utiliser dans votre programme et ajoutez les classes correspondantes. Il peut s'agir d'objets concrets (client, maison, billet, etc.) ou d'objets abstraits (compte, relation bancaire, etc.). N'oubliez pas que la modularisation n'est pas une science exacte. Chaque programmeur décide des classes qu'il trouve utiles pour son programme. C'est souvent l'étape la plus difficile d'un projet de programmation.
- Transférez le code concernant les objets dans les classes. Utilisez le mot-clé private pour encapsuler les variables et les méthodes d'instance qui ne seront pas utilisées à l'extérieur de la classe. Chaque méthode (auxiliaire ou d'instance) devrait être courte et sans trop d'instructions détaillées. Les identificateurs (noms des variables et des méthodes) devraient être parlants.
Exemple d'exécution du programme:
Données avant le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1000.0 francs
Compte d'épargne: 2000.0 francs
Client Alexandra de Lausanne
Compte privé: 3000.0 francs
Compte d'épargne: 4000.0 francs
Données après le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1010.0 francs
Compte d'épargne: 2040.0 francs
Client Alexandra de Lausanne
Compte privé: 3030.0 francs
Compte d'épargne: 4080.0 francs
Code donné:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
class Banque1 { public static void main(String args[]) { // Données pour tous les comptes privés (taux d'intérêt): double taux1 = 0.01; // Données pour tous les comptes d'épargne (taux d'intérêt): double taux2 = 0.02; // Données pour le premier client (nom et ville): String nom1 = "Pedro"; String ville1 = "Genève"; // Données pour le compte privé du premier client (solde): double solde1PremierClient = 1000.0; // Données pour le compte d'épargne du premier client (solde): double solde2PremierClient = 2000.0; // Données pour le deuxième client (nom et ville): String nom2 = "Alexandra"; String ville2 = "Lausanne"; // Données pour le compte privé du deuxième client (solde): double solde1DeuxiemeClient = 3000.0; // Données pour le compte d'épargne du deuxième client (solde): double solde2DeuxiemeClient = 4000.0; // Afficher les données du premier client: afficherClient(nom1, ville1, solde1PremierClient, solde2PremierClient); // Afficher les données du deuxième client: afficherClient(nom2, ville2, solde1DeuxiemeClient, solde2DeuxiemeClient); // Bouclement du compte privé du premier client: solde1PremierClient = bouclerCompte(solde1PremierClient, taux1); // Bouclement du compte d'épargne du premier client: solde2PremierClient = bouclerCompte(solde2PremierClient, taux2); // Bouclement du compte privé du deuxième client: solde1DeuxiemeClient = bouclerCompte(solde1DeuxiemeClient, taux1); // Bouclement du compte d'épargne du deuxième client: solde2DeuxiemeClient = bouclerCompte(solde2DeuxiemeClient, taux2); // Afficher les données du premier client: afficherClient(nom1, ville1, solde1PremierClient, solde2PremierClient); // Afficher les données du deuxième client: afficherClient(nom2, ville2, solde1DeuxiemeClient, solde2DeuxiemeClient); } static void afficherClient(String nom, String ville, double solde1, double solde2) { // Cette méthode affiche les données du client * System.out.println("Client " + nom + " de " + ville); System.out.println(" Compte privé: " + solde1 + " francs"); System.out.println(" Compte d'épargne: " + solde2 + " francs"); } static double bouclerCompte(double solde, double taux) { // Cette méthode ajoute les intérêts au solde */ double interets = taux * solde; double nouveauSolde = solde + interets; return nouveauSolde; } } |
Banque avec des clientes (Niveau 1)
Vous avez bien noté que l'affichage du programme Banque1 ne fait pas de différence entre les clientes et les clients. Ceci est facile à corriger dans la version orientée objets du programme, par exemple en ajoutant une variable d'instance booléenne masculin à la classe Client (si vous en avez une) et en testant sa valeur dans la méthode d'affichage. Modifiez votre programme, par exemple sous le nom de Banque3, pour qu'il affiche "cliente" au lieu de "client" comme suit:
Données avant le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1000.0 francs
Compte d'épargne: 2000.0 francs
Cliente Alexandra de Lausanne
Compte privé: 3000.0 francs
Compte d'épargne: 4000.0 francs
Données après le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1010.0 francs
Compte d'épargne: 2040.0 francs
Cliente Alexandra de Lausanne
Compte privé: 3030.0 francs
Compte d'épargne: 4080.0 francs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
class Banque2 { public static void main(String[] args) { // Variables locales pour les taux d'intérêts (afin d'éviter de // répéter les mêmes chiffres pour chaque client): double taux1 = 0.01; double taux2 = 0.02; // Construction des deux clients: Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0); Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0); System.out.println("Données avant le bouclement des comptes:"); c1.afficher(); c2.afficher(); // Bouclement des comptes des deux clients: c1.boucler(); c2.boucler(); System.out.println("Données après le bouclement des comptes:"); c1.afficher(); c2.afficher(); } } class Client { private String nom; private String ville; private Compte cpt1, cpt2; public Client(String nom, String ville, double taux1, double solde1, double taux2, double solde2) { this.nom = nom; this.ville = ville; // Construction d'un compte privé: cpt1 = new Compte(taux1, solde1); // Construction d'un compte d'épargne: cpt2 = new Compte(taux2, solde2); } public void afficher() { // Cette méthode affiche les données du client System.out.println(" Client " + nom + " de " + ville); System.out.println(" Compte privé: " + cpt1.getSolde() + " francs"); System.out.println(" Compte d'épargne: " + cpt2.getSolde() + " francs"); } public void boucler() { // Cette méthode boucle les deux comptes du client cpt1.boucler(); cpt2.boucler(); } } class Compte { private double taux; private double solde; public Compte(double taux, double solde) { this.taux = taux; this.solde = solde; } public double getSolde() { return solde; } public void boucler() { // Cette méthode ajoute les intérêts au solde double interets = taux * solde; solde = solde + interets; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class Banque3 { public static void main(String[] args) { // ... comme avant // Construction des deux clients, notez l'argument booléen: Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0, true); // Nouveau Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0, false); // Nouveau // ... comme avant } } class Client { private String nom; private String ville; private Compte cpt1, cpt2; private boolean masculin; // Nouvelle variable d'instance // Méthode constructeur, notez le paramètre booléen: public Client(String nom, String ville, double taux1, double solde1, double taux2, double solde2, boolean masculin) { // Nouveau this.nom = nom; this.ville = ville; cpt1 = new Compte(taux1, solde1); cpt2 = new Compte(taux2, solde2); this.masculin = masculin; // Nouveau } public void afficher() { if (masculin) // Nouvelle instruction if..else System.out.print(" Client "); else System.out.print(" Cliente "); System.out.println(nom + " de " + ville); System.out.println(" Compte privé: " + cpt1.getSolde() + " francs"); System.out.println(" Compte d'épargne: " + cpt2.getSolde() + " francs"); } // ... comme avant } class Compte { // ... comme avant } |
class Banque2 {
public static void main(String[] args) {
// Variables locales pour les taux d'intérêts (afin d'éviter de
// répéter les mêmes chiffres pour chaque client):
double taux1 = 0.01;
double taux2 = 0.02;
// Construction des deux clients:
Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0);
Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0);
System.out.println("Données avant le bouclement des comptes:");
c1.afficher();
c2.afficher();
// Bouclement des comptes des deux clients:
c1.boucler();
c2.boucler();
System.out.println("Données après le bouclement des comptes:");
c1.afficher();
c2.afficher();
}
}
class Client {
private String nom;
private String ville;
private Compte cpt1, cpt2;
public Client(String nom, String ville, double taux1, double solde1,
double taux2, double solde2) {
this.nom = nom;
this.ville = ville;
// Construction d'un compte privé:
cpt1 = new Compte(taux1, solde1);
// Construction d'un compte d'épargne:
cpt2 = new Compte(taux2, solde2);
}
public void afficher() {
// Cette méthode affiche les données du client
System.out.println(" Client " + nom + " de " + ville);
System.out.println(" Compte privé: " +
cpt1.getSolde() + " francs");
System.out.println(" Compte d'épargne: " +
cpt2.getSolde() + " francs");
}
public void boucler() {
// Cette méthode boucle les deux comptes du client
cpt1.boucler();
cpt2.boucler();
}
}
class Compte {
private double taux;
private double solde;
public Compte(double taux, double solde) {
this.taux = taux;
this.solde = solde;
}
public double getSolde() {
return solde;
}
public void boucler() {
// Cette méthode ajoute les intérêts au solde
double interets = taux * solde;
solde = solde + interets;
}
}
Exercice POO de base calcul de la surface
Modifier un petit programme calculant des surfaces
POO de base
Le fichier Surfaces.java contient les déclarations de trois classes: Surfaces, Terrain et Rectangle.
- La classe Rectangle définit des objets de type rectangle, la classe Terrain définit des objets constitués de deux rectangles et permet de calculer leur surface totale.
- Etudiez le code contenu dans le fichier Surfaces.java pour en comprendre les structures et fonctionnalités.
- Incorporez le fichier dans Eclipse. Vérifiez qu'il y a vraiment un fichier .class correspondant à chaque classe déclarée dans le fichier compilé.
- Essayez de démarrer la classe Rectangle. Vous aurez un message d'erreur (lequel ?) car cette classe n'a pas de méthode main et n'est donc pas démarrable. Démarrez le programme à l'aide de la classe qui a une méthode main.
- Modifiez le code comme suit:
- Calculez la surface d'un terrain composé de 3 rectangles et de 2 cercles. Vous pouvez soit entrer les données directement dans le code, soit demander à l'utilisateur de les entrer au clavier. Par exemple, vous aurez une surface totale de 398.9999698556466 si vos 3 rectangles sont de largeur/hauteur 1.0/2.0, 3.0/4.0 et 5.0/6.0 et si vos 2 cercles sont de rayon 7.0 et 8.0
- Dans ce but, il faut ajouter une classe Cercle au programme. Cette classe peut, par exemple, avoir une variable d'instance rayon et une méthode d'instance calculerSurface. La surface d'un cercle est calculée par la formule ? · r2. Vous pouvez utiliser la constante prédéfinie Math.PI.
- Rappelez-vous que plusieurs classes peuvent utiliser le même nom pour leurs méthodes d'instance. Il n'y a aucun conflit car une méthode d'instance est toujours appelée à travers un objet d'une classe précise, ce qui permet de choisir la bonne méthode à exécuter. Vous pouvez donc, par exemple, avoir une méthode calculerSurface dans la classe Rectangle ainsi que dans la classe Cercle. Choisissez toujours l'identificateur le plus parlant possible pour vos variables, méthodes et classes.
Code donné:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/* Dans ce programme, les 2 rectangles sont encapsulés dans un objet de type Terrain qui s'occupe de calculer et d'afficher la surface totale. Le mot-clé private a été utilisé le plus possible dans toutes les classes. La classe Rectangle met aussi à disposition des méthodes get et set pour ses variables (il s'agit d'un service que le programmeur de la classe peut offrir à ses utilisateurs s'il le juge utile). */ class Surfaces { public static void main(String[] args) { // Construction d'un terrain: Terrain t = new Terrain(1.0, 2.0, 3.0, 4.0); t.afficherSurfaceTotale(); } } class Terrain { private Rectangle r1; private Rectangle r2; public Terrain(double l1, double h1, double l2, double h2) { // Construction des 2 rectangles définissant le terrain: r1 = new Rectangle(l1, h1); r2 = new Rectangle(l2, h2); } private double calculerSurfaceTotale() { return r1.calculerSurface() + r2.calculerSurface(); } public void afficherSurfaceTotale() { double surfaceTotale = calculerSurfaceTotale(); System.out.println("La surface totale est " + surfaceTotale); } } class Rectangle { private double largeur; private double hauteur; public Rectangle(double largeur, double hauteur) { this.largeur = largeur; this.hauteur = hauteur; } public void setLargeur(double largeur) { this.largeur = largeur; } public double getLargeur() { return largeur; } public void setHauteur(double hauteur) { this.hauteur = hauteur; } public double getHauteur() { return hauteur; } public double calculerSurface() { return (largeur * hauteur); } } |
|
Fichiers:
|
Il s'agit ici de modifier le codage de la classe Terrain de sorte à décrire un terrain non plus comme étant constitué de 2 rectangles mais de 3 rectangles et 2 cercles. Commençons par décrire la nouvelle classe, Cercle qui nous est nécessaire :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Cercle { private double rayon; public Cercle (double rayon) { this.rayon = rayon; } public void setRayon (double rayon) { this.rayon = rayon; } public double getRayon () { return rayon; } public double calculerSurface () { return (Math.PI * rayon * rayon); } } |
Il faut ensuite mettre à jour la classe Terrain en lui ajoutant les 3 attributs supplémentaires, en modifiant son constructeur et en modifier sa méthode de calcul de surface. On voit que cette dernière modification est complètement transparente pour l'utilisateur externe de la classe Terrain. Les méthodes par lesquelles il interagit avec cette classe (interface d'utilisation ou API) restent inchangées (à part le constructeur). La méthode calculerSurfaceTotale qui a été modifiée est en effet privée et la méthode d'affichage, publique parce qu'utile à l'utilisateur externe, n'a pas été modifiée.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Terrain { private Rectangle r1; private Rectangle r2; private Rectangle r3; private Cercle c1; private Cercle c2; public Terrain (double l1, double h1, double l2, double h2, double l3, double h3, double rayon1, double rayon2) { // Construction des 3 rectangles definissant le terrain: r1 = new Rectangle(l1, h1); r2 = new Rectangle(l2, h2); r3 = new Rectangle(l3, h3); c1 = new Cercle(rayon1); c2 = new Cercle(rayon2); } private double calculerSurfaceTotale () { return r1.calculerSurface() + r2.calculerSurface() + r3.calculerSurface() + c1.calculerSurface() + c2.calculerSurface(); } public void afficherSurfaceTotale () { double surfaceTotale = calculerSurfaceTotale(); System.out.println("La surface totale est " + surfaceTotale); } } |
Voici le code complet du programme modifié:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/* Ce programme calcule la surface d'un terrain composé de 3 rectangles et de 2 cercles. */ class Surfaces { public static void main (String[] args) { // Construction d'un terrain: Terrain t = new Terrain(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); t.afficherSurfaceTotale(); } } class Terrain { private Rectangle r1; private Rectangle r2; private Rectangle r3; private Cercle c1; private Cercle c2; public Terrain (double l1, double h1, double l2, double h2, double l3, double h3, double rayon1, double rayon2) { // Construction des 3 rectangles définissant le terrain: r1 = new Rectangle(l1, h1); r2 = new Rectangle(l2, h2); r3 = new Rectangle(l3, h3); c1 = new Cercle(rayon1); c2 = new Cercle(rayon2); } private double calculerSurfaceTotale () { return r1.calculerSurface() + r2.calculerSurface() + r3.calculerSurface() + c1.calculerSurface() + c2.calculerSurface(); } public void afficherSurfaceTotale () { double surfaceTotale = calculerSurfaceTotale(); System.out.println("La surface totale est " + surfaceTotale); } } class Rectangle { private double largeur; private double hauteur; public Rectangle (double largeur, double hauteur) { this.largeur = largeur; this.hauteur = hauteur; } public void setLargeur (double largeur) { this.largeur = largeur; } public double getLargeur () { return largeur; } public void setHauteur (double hauteur) { this.hauteur = hauteur; } public double getHauteur () { return hauteur; } public double calculerSurface () { return (largeur * hauteur); } } class Cercle { private double rayon; public Cercle (double rayon) { this.rayon = rayon; } public void setRayon (double rayon) { this.rayon = rayon; } public double getRayon () { return rayon; } public double calculerSurface () { return (Math.PI * rayon * rayon); } } |
Exercice POO de base - trouver les erreurs
|
But:
|
Trouver l'erreur dans un programme donné | |||
|
Thème:
|
POO de base | |||
|
Fichiers:
|
Erreurs.java |
Le fichier Erreurs.java contient les déclarations de deux classes. La classe Erreurs contient une méthode main et sert à démarrer le programme. La classe GrillePain sert à représenter des grille-pains dans le programme sous forme d'objets dotés de deux variables d'instance: l'année de fabrication et le nombre de tranches que l'appareil peut griller. Il y a également une méthode d'instance afficherVariables que l'on peut appliquer sur un objet de type GrillePain afin d'afficher les valeurs de ses variables d'instance.
- Eclipse vous signale des messages d'erreurs à propos de ce programme. Pourquoi? Corrigez-les.
- L'affichage lors de l'exécution montre que la variable d'instance nbTranches a la valeur 0 pour les deux grille-pains même si l'on a envoyé une autre valeur à la méthode constructeur. Pourquoi? Corrigez le programme.
Exemple d'exécution du programme (après la première correction):
Objet de type GrillePain avec variables d'instance
annee = 1995 et nbTranches = 2
Objet de type GrillePain avec variables d'instance
annee = 1998 et nbTranches = 4
Code donné:
|
Erreurs.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Erreurs { public static void main(String[] args) { GrillePain g1 = new GrillePain(1995, 2); g1.afficherVariables(); GrillePain g2 = new GrillePain(1998, 4); g2.afficherVariables(); } } class GrillePain { private int annee; private int nbTranches; private GrillePain(int a, int nbTranches) { annee = a; nbTranches = nbTranches; } private void afficherVariables() { System.out.println ("Objet de type GrillePain avec variables d'instance année = " + annee + " et nbTranches = " + nbTranches); } } |
|
Fichiers:
|
Erreurs.java |
- Le programmeur a trop utilisé le mot-clé private au point que l'on ne peut même pas accéder à la méthode constructeur depuis l'extérieur de la classe, ni à la méthode afficherVariables(). Il faut rendre ces deux méthodes publiques en supprimant le mot-clé private.
- Les variables d'instance (mais pas les variables locales) reçoivent toujours des valeurs par défaut. Si la variable d'instance nbTranches n'est pas initialisée, elle aura donc la valeur 0. Dans la méthode constructeur, il y a une situation de shadowing où le paramètre a le même nom que la variable d'instance. Il faut utiliser l'objet this pour différencier les deux et ainsi affecter la valeur du paramètre nbTranches à la variable d'instance nbTranches.
|
Erreurs.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* Version corrigée */ class Erreurs { public static void main (String[] args) { GrillePain g1 = new GrillePain(1995, 2); g1.afficherVariables(); GrillePain g2 = new GrillePain(1998, 4); g2.afficherVariables(); } } class GrillePain { private int annee; private int nbTranches; public GrillePain (int a, int nbTranches) { // !!! pas de private annee = a; this.nbTranches = nbTranches; // !!! this } public void afficherVariables() { // !!! pas de private System.out.println ("Objet de type GrillePain avec variables d'instance année = " + annee + " et nbTranches = " + nbTranches); } } |
Exercice POO de base stockage en mémoire
|
But:
|
Indiquer l'affichage d'un programme donné | |||
|
Thème:
|
POO de base | |||
|
Fichiers:
|
Memoire.java |
Indiquez l'affichage du programme Memoire.java. Abstenez-vous d'exécuter le programme avant de répondre à la question. Faites toujours très attention aux détails en répondant à ce genre de question.
Il s'agit de comprendre les différentes façons de stocker en mémoire une variable de type primitif et une variable de type objet. La classe A est déclarée dans le même fichier que la classe Memoire.
Memoire.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class Memoire { public static void main (String args[]) { int i = 1; afficher(i); modifier(i); afficher(i); System.out.println("-----"); A a1 = new A(1); a1.afficher(); a1.modifier(); a1.afficher(); System.out.println("-----"); A a2 = new A(2); a2.afficher(); A a3 = new A(3); a3.afficher(); System.out.println("-----"); a3 = a2; a2.afficher(); a3.afficher(); System.out.println("-----"); a2.modifier(); a3.modifier(); a2.afficher(); a3.afficher(); System.out.println("-----"); } static void modifier (int i) { i++; } static void afficher (int i) { System.out.println(i); } } class A { private int i; A (int i) { this.i = i; } void modifier () { i++; } void afficher () { System.out.println(i); } } |
Affichage du programme:
1 1 ----- 1 2 ----- 2 3 ----- 2 2 ----- 4 4 -----
Exercice POO de base concevoir un programme de géométrie
|
But:
|
Concevoir entièrement un petit programme orienté-objet | |||
|
Thème:
|
POO de base | |||
| - |
Ecrivez un programme Geometrie qui permet à l'utilisateur d'entrer les coordonnées (x, y) des sommets d'un triangle. Le programme affiche ensuite le périmètre du triangle ainsi qu'un message indiquant s'il s'agit d'un triangle isocèle. Votre programme doit être orienté objets. Indications:
- Un triangle est isocèle si au moins deux côtés ont la même longueur.
- La formule pour calculer la distance entre deux points (x1, y1) et (x2, y2) est: racine carrée de (x1 - x2)2 + (y1 - y2)2.
- Java met à disposition la méthode Math.sqrt() pour calculer la racine carrée. Cette méthode prend un nombre non-négatif en paramètre. Exemple:
double a = Math.sqrt(9.0); // la valeur 3.0 sera affectée à a
Exemple d'affichage du programme pour un triangle isocèle:
Construction d'un nouveau point Veuillez entrer x : 0 Veuillez entrer y : 0 Construction d'un nouveau point Veuillez entrer x : 2.5 Veuillez entrer y : 2.5 Construction d'un nouveau point Veuillez entrer x : 0 Veuillez entrer y : 5 Périmètre : 12.071067811865476 Le triangle est isocèle
Dans cet exercice, vous élaborerez un programme orienté objets de manière indépendante pour la première fois. Si vous n'avez pas le temps de faire cet exercice, n'oubliez pas d'en étudier le corrigé.
Voici quelques indications en vrac qui peuvent vous être utiles. Ne les lisez pas si vous voulez être complètement indépendant ...
- Réfléchissez aux objets que vous aimeriez utiliser dans le programme. Vous pourriez par exemple représenter le triangle par une classe Triangle et ses points par une classe Point. Une troisième classe Geometrie pourrait héberger la méthode main.
- Réfléchissez aux variables et méthodes d'instance qui seraient utiles pour les classes Triangle et Point.
- Un objet de type Point a typiquement les coordonnées x et y. Un objet de type Triangle a trois sommets qui peuvent être représentés par des objets de type Point.
- Les coordonnées des points peuvent par exemple être entrées dans la méthode constructeur de la classe Point à l'aide de la méthode scanner.nextDouble(). Dans ce cas, la méthode constructeur n'a pas de paramètres.
- Le périmètre d'un triangle peut être calculé comme la somme des distances entre les trois sommets.
- Une méthode calculerDistance() peut être utile pour calculer la distance entre deux points. La formule est indiquée ci-dessus. Si cette méthode se trouve dans la classe Point, le premier point est accessible sous forme de l'objet utilisé pour appeler la méthode (l'objet actuel this), mais il faut envoyer le deuxième point en paramètre. Si les variables d'instance x et y du deuxième point sont privées, il faut mettre à disposition des méthodes getX() et getY() afin de pouvoir accéder aux valeurs nécessaires pour le calcul.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
import java.util.Scanner; class Geometrie { /** * Le programme principal se content de construire un * triangle, d'afficher son perimètre et d'afficher * s'il est isocèle ou non. */ public static void main(String[] args) { Triangle t = new Triangle(); double perimetre = t.calculerPerimetre(); System.out.println("Périmètre : " + perimetre); boolean isocele = t.testerIsocele(); if (isocele) System.out.println("Le triangle est isocèle"); else System.out.println("Le triangle n'est pas isocèle"); } } class Triangle { private Point p1, p2, p3; private double longueur1, longueur2, longueur3; /** * La constructeur d'un Triangle fait appel * au constructeur de Point. Ce dernier lit les * coordonnées depuis le terminal. */ public Triangle() { // Construction de trois points: p1 = new Point(); p2 = new Point(); p3 = new Point(); // Les distances sont calculées et stockées dans des variables // d'instance. Les méthodes calculerPerimetre et testerIsocele // peuvent ainsi accéder aux valeurs précalculées et nous évitons // de les recalculer plusieurs fois. longueur1 = p1.calculerDistance(p2); longueur2 = p2.calculerDistance(p3); longueur3 = p3.calculerDistance(p1); } /** * Calcul du perimètre de l'instance courante (this). * @return le perimetre sous la forme d'un double */ public double calculerPerimetre() { return (longueur1 + longueur2 + longueur3); } /** * Teste si l'instance courante (this) est un triangle isocèle * @return true si le triangle est isocèle et false sinon */ public boolean testerIsocele() { if ((longueur1 == longueur2) || (longueur2 == longueur3) || (longueur3 == longueur1)) { return true; } else { return false; } } } class Point { private static Scanner scanner = new Scanner(System.in); private double x, y; public Point() { System.out.println("Construction d'un nouveau point"); System.out.print(" Veuillez entrer x : "); x = scanner.nextDouble(); System.out.print(" Veuillez entrer y : "); y = scanner.nextDouble(); } public double getX() { return x; } public double getY() { return y; } /** * Calcule la distance entre this et un point p * @param p un Point par rapport auquel on calcule la distance * @return la distance de this à p */ public double calculerDistance(Point p) { // Calcule la distance entre deux points. Le premier point est // l'objet actuel (this). Le deuxième point (p) est envoyé en // paramètre. double x1 = this.x; double y1 = this.y; double x2 = p.getX(); double y2 = p.getY(); double xdiff = x1 - x2; double ydiff = y1 - y2; double somme = xdiff * xdiff + ydiff * ydiff; double distance = Math.sqrt(somme); return distance; } } |
Exercice POO de base gestion de pharmacie
|
But:
|
Ecrire un programme orienté objets qui permet de gérer une pharmacie | |||
|
Thème:
|
POO de base | |||
|
Fichiers:
|
Cet exercice a été donné en série notée une des années précédentes. Il constitue donc un bon entraînement ! Il est de niveau 3 si vous débutez avec la POO mais devrait devenir beaucoup plus accessible dès que les concepts de base sont absorbés.
Écrivez un programme orienté objets qui permet de gérer une pharmacie. La classe principale débute comme suit. Il s'agira de la compléter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import java.util.Scanner; class Pharmacie { private static Scanner scanner = new Scanner(System.in); public static void main (String args[]) { Client[] clients = new Client[2]; Medicament[] medicaments = new Medicament[2]; clients[0] = new Client("Malfichu",0.0); clients[1] = new Client("Palichon",0.0); medicaments[0] = new Medicament("Aspiron", 20.40, 5); medicaments[1] = new Medicament("Rhinoplexil",19.15, 5); int choix; do { choix = menu(); switch (choix) { case 1 : achat(clients, medicaments); break; case 2 : approvisionnement(medicaments); break; case 3 : affichage(clients, medicaments); break; case 4: quitter(); } } while (choix < 4); } // Les méthodes utilitaires static int menu() { int choix = 0; System.out.println(); System.out.println(); System.out.println("1 : Achat de médicament"); System.out.println("2 : Approvisionnement en médicaments"); System.out.println("3 : Etats des stocks et des crédits"); System.out.println("4 : Quitter"); while ((choix != 1) && (choix != 2) && (choix != 3) && (choix != 4)) { choix = scanner.nextInt(); } return choix; } // Méthodes auxiliaires à compléter } // Autres classes à compléter |
La pharmacie gère des clients et des médicaments. Un client est caractérisé par un nom et un crédit. Le crédit représente la somme que ce client doit à la pharmacie. Le crédit peut être négatif si le client a versé plus d'argent que le montant. Un médicament est caractérisé par un nom (de type String), un prix (de type double) et un stock (de type int). Les méthodes à compléter auront les caractéristiques suivantes:
- affichage(..) permet d'afficher les clients et leurs crédits respectifs ainsi que les médicaments et leurs stocks respectifs.
- approvisionner(..) permet d'approvisionner le stock d'un médicament. Le nom du médicament à approvisionner ainsi que la quantité à ajouter au stock doivent être lus depuis le terminal. Lorsque le nom du médicament est introduit, il faut vérifier qu'il s'agit bien d'un nom connu dans la liste des médicaments de la pharmacie. Le programme doit boucler jusqu'à introduction d'un nom correct. Cette procédure de vérification sera prise en charge par la méthode lireMedicament(..) décrite plus bas.
-
achat(..) permet de traiter un achat fait par un client. l'achat porte sur un médicament donné dans une quantité donnée. Pour cette transaction le client paie un certain prix. Une opération d'achat aura pour effet de déduire la quantité achetée du stock du médicaments correspondant et d'augmenter le crédit du client (d'un montant équivalent au montant de l'achat moins la somme payée).
Les noms du client et du médicament doivent être lus depuis le terminal. Le programme doit boucler jusqu'à introduction de noms connus aussi bien pour les clients que les médicament. Ces procédures de vérification seront prises en charge par les méthodes lireClient et lireMedicament (voir plus bas). La quantité achetée et le montant payé sont aussi lus depuis le terminal. Ils seront supposés corrects. - quitter(..) affiche le message ``programme terminé!''.
- Vous définirez une méthode auxiliaire lireClient(..) prenant comme paramètre un tableau de clients. Elle permettra de lire le nom d'un client depuis le terminal et de vérifier si ce client existe dans le tableau des clients. Dans ce cas le client sera retourné. Cette méthode doit boucler jusqu'à ce qu'un client soit trouvé. Elle sera utilisée par la méthode achat(..). Une méthode similaire, lireMedicament(..) sera fournie pour les médicaments. Elle sera utilisée par les méthodes achat(..) et approvisionnement(..).
- Vous êtes libre de définir, en plus de ces méthodes, toutes celles que vous jugerez nécessaires.
Lors de la programmation, il vous est demandé de respecter scrupuleusement les indications suivantes:
- Votre programme doit être bien modularisé à la fois sous forme de méthodes auxiliaires de la méthode main() et sous forme de classes pour les objets du programme. En particulier:
- Chaque variable et méthode doit être déclarée dans la classe la plus adaptée.
- Dans chaque classe liée à un objet, il faut utiliser le mot-clé private autant que possible. En particulier, toutes les variables d'instances seront privées.
- Votre programme doit montrer une utilisation judicieuse de tableaux aux endroits adaptés.
- la comparaison de deux chaines s1 et s2 se fera au moyen de la méthode java equals() (s1.equals(s2) retourne true si s1 et s2 sont identiques).
- Vous pouvez utiliser les méthodes scanner.nextInt(),
scanner.nextDouble() et scanner.nextLine().
Exemple d'exécution:
> java Pharmacie 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 2 Nom du medicament?: Aspiron Donner la Quantité : 2 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 3 Affichage des stocks Stock du médicament Aspiron :7 Stock du médicament Rhinoplexil :5 Affichage des crédits Crédit du client Malfichu :0.0 Crédit du client Palichon :0.0 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 1 Nom du client?: Malfichu Nom du medicament?: Aspiron quel est le montant du paiement? 30.0 quelle est la quantité achetée? 3 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 3 Affichage des stocks Stock du médicament Aspiron :4 Stock du médicament Rhinoplexil :5 Affichage des crédits Crédit du client Malfichu :31.199999999999996 Crédit du client Palichon :0.0 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 1 Nom du client?: Palichon Nom du medicament?: Aspiron quel est le montant du paiement? 5 quelle est la quantité achetée? 5 Achat Impossible. Quantité insuffisante 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 3 Affichage des stocks Stock du médicament Aspiron :4 Stock du médicament Rhinoplexil :5 Affichage des crédits Crédit du client Malfichu :31.199999999999996 Crédit du client Palichon :0.0 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 1 Nom du client?: Palichon Nom du medicament?: Rhinoplexil quel est le montant du paiement? 200 quelle est la quantité achetée? 5 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 3 Affichage des stocks Stock du médicament Aspiron :4 Stock du médicament Rhinoplexil :0 Affichage des crédits Crédit du client Malfichu :31.199999999999996 Crédit du client Palichon :-104.25 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 1 Nom du client?: Febril Client inconnu. Veuilliez recommencer Malfichu Nom du medicament?: Placebo Medicament inconnu. Veuilliez recommencer Aspiron quel est le montant du paiement? 2 quelle est la quantité achetée? 1 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 3 Affichage des stocks Stock du médicament Aspiron :3 Stock du médicament Rhinoplexil :0 Affichage des crédits Crédit du client Malfichu :49.599999999999994 Crédit du client Palichon :-104.25 1 : Achat de médicament 2 : Approvisionnement en médicaments 3 : Etats des stocks et des crédits 4 : Quitter 4 Programme terminé!
Amélioration du code objet
Une pharmacie peut être vue comme une classe d'objets ayant pour attribut un tableau de clients et un tableau de médicaments. Copiez votre programme Pharmacie.java dans un fichier GestionPharmacie.java. Renommer la classe Pharmacie dans
GestionPharmacie.java en Pharmacie1. Déplacez la méthode main() pour la placer dans la classe GestionPharmacie.java. Il vous est demandé de
- Modifier la classe Pharmacie1 de sorte à la doter des attributs sus-mentionnés.
- Transformer les méthodes statiques se rapportant uniquement aux attributs de Pharmacie1 en des méthodes d'instances.
Indication: si vous avez respecté les directives de la première question, les méthodes lireClient() et lireMedicament() par exemple, deviennent des méthodes d'instance de la classe Pharmacie1 - Adapter la méthode main() de la classe GestionPharmacie de manière appropriée.
- Placez les méthodes auxiliaires qui n'ont pu être transformées en méthodes d'instance de Pharmacie1 dans GestionPharmacie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
import java.util.Scanner; class Pharmacie { private static Scanner scanner = new Scanner(System.in); public static void main(String args[]) { Client[] clients = new Client[2]; Medicament[] medicaments = new Medicament[2]; clients[0] = new Client("Malfichu", 0.0); clients[1] = new Client("Palichon", 0.0); medicaments[0] = new Medicament("Aspiron", 20.40, 5); medicaments[1] = new Medicament("Rhinoplexil", 19.15, 5); int choix; do { choix = menu(); switch (choix) { case 1: achat(clients, medicaments); break; case 2: approvisionnement(medicaments); break; case 3: affichage(clients, medicaments); break; case 4: quitter(); } } while (choix < 4); } // Les méthodes utilitaires static int menu() { int choix = 0; System.out.println(); System.out.println(); System.out.println("1 : Achat de médicament"); System.out.println("2 : Approvisionnement en médicaments"); System.out.println("3 : Etats des stocks et des crédits"); System.out.println("4 : Quitter"); while ((choix != 1) && (choix != 2) && (choix != 3) && (choix != 4)) { choix = scanner.nextInt(); } // se debarasser du \n scanner.nextLine(); return choix; } /** * Méthode auxiliaire de main permettant à un client * d'acheter un médicament */ static void achat(Client[] clients, Medicament[] medicaments) { Client client = lireClient(clients); Medicament medicament = lireMedicament(medicaments); double paiement = lirePaiement(); int quantite = lireQuantite(); if (quantite <= medicament.getStock()) { medicament.diminuerStock(quantite); client.augmenterCredit((medicament.getPrix() * quantite) - paiement); } else System.out.println("Achat Impossible. Quantité insuffisante"); } /** * Méthode auxiliaire de main permettant d'augmenter le * stock d'un médicament */ static void approvisionnement(Medicament[] medicaments) { Medicament medicament = lireMedicament(medicaments); System.out.println("Donner la Quantité : "); int quantite = scanner.nextInt(); // se debarasser du \n scanner.nextLine(); medicament.augmenterStock(quantite); } /** * Méthode auxiliaire de main permettant d'afficher les * données stockées dans les tableaux clients et medicaments */ static void affichage(Client[] clients, Medicament[] medicaments) { System.out.println("Affichage des stocks"); for (int i = 0; i < medicaments.length; i++) { System.out.println("Stock du médicament " + medicaments[i].getNom() + " :" + medicaments[i].getStock()); } System.out.println("Affichage des crédits"); for (int i = 0; i < clients.length; i++) { System.out.println("Crédit du client " + clients[i].getNom() + " :" + clients[i].getCredit()); } } /** * Retourne l'objet Client associé à un nom (String) * Le nom est lu et redemandé tant qu'il ne correspond * pas au nom d'un client contenu dans le tableau clients */ static Client lireClient(Client[] clients) { String nom; boolean trouve = false; Client c = null; System.out.println("Nom du client?:"); do { nom = scanner.nextLine(); for (int i = 0; (!trouve && i < clients.length); i++) { if ((clients[i].getNom()).equals(nom)) { trouve = true; c = clients[i]; } } if (!trouve) { System.out.println("Client inconnu. Veuilliez recommencer"); } } while (!trouve); return c; } /** * Retourne l'objet Medicament associé à un nom (String) * Le nom est lu et redemandé tant qu'il ne correspond * pas au nom d'un médicament contenu dans le tableau medicaments */ static Medicament lireMedicament(Medicament[] medicaments) { String nom; boolean trouve = false; Medicament m = null; System.out.println("Nom du medicament?:"); do { nom = scanner.nextLine(); for (int i = 0; (!trouve && i < medicaments.length); i++) { if ((medicaments[i].getNom()).equals(nom)) { trouve = true; m = medicaments[i]; } } if (!trouve) { System.out.println("Medicament inconnu. Veuilliez recommencer"); } } while (!trouve); return m; } static double lirePaiement() { double paiement; System.out.println("quel est le montant du paiement?"); paiement = scanner.nextDouble(); scanner.nextLine(); return paiement; } static int lireQuantite() { int quantite; System.out.println("quelle est la quantité achetée?"); quantite = scanner.nextInt(); scanner.nextLine(); return quantite; } static void quitter() { System.out.println("Programme terminé!"); } } // Les classes d'objets class Client { // Un client est caractérisé par son nom et un crédit. private String nom = ""; private double credit = 0.0; public Client(String nom, double credit) { this.nom = nom; this.credit = credit; } public void augmenterCredit(double montant) { credit = credit + montant; } public void diminuerCredit(double montant) { credit = credit - montant; } public double getCredit() { return credit; } public String getNom() { return nom; } } class Medicament { // un médicament a un nom, un prix et une quantité en stock private String nom; private double prix; private int stock; public Medicament(String nom, double prix, int stock) { this.nom = nom; this.prix = prix; this.stock = stock; } public void augmenterStock(int quantite) { stock = stock + quantite; } public void diminuerStock(int quantite) { stock = stock - quantite; } public int getStock() { return stock; } public double getPrix() { return prix; } public String getNom() { return nom; } } |
Amélioration du code objet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
import java.util.Scanner; class GestionPharmacie { protected static Scanner scanner = new Scanner(System.in); /** * Le programme principal crée un objet Pharmacie * sur lequel les opérations suivantes peuvent être effectuées: * - achat (d'un médicament par un client), * - approvisionnement (ajout d'un médicament au stock) * - affichage (des données relatives à la pharmacie */ public static void main(String args[]) { Client[] clients = new Client[2]; Medicament[] medicaments = new Medicament[2]; clients[0] = new Client("Malfichu", 0.0); clients[1] = new Client("Palichon", 0.0); medicaments[0] = new Medicament("Aspiron", 20.40, 5); medicaments[1] = new Medicament("Rhinoplexil", 19.15, 5); Pharmacie1 p = new Pharmacie1(clients, medicaments); int choix; do { choix = menu(); switch (choix) { case 1: p.achat(); break; case 2: p.approvisionnement(); break; case 3: p.affichage(); break; case 4: quitter(); break; } } while (choix < 4); } // Les méthodes utilitaires static int menu() { int choix = 0; System.out.println(); System.out.println(); System.out.println("1 : Achat de médicament"); System.out.println("2 : Approvisionnement en médicaments"); System.out.println("3 : Etats des stocks et des crédits"); System.out.println("4 : Quitter"); while ((choix != 1) && (choix != 2) && (choix != 3) && (choix != 4)) { choix = scanner.nextInt(); } return choix; } static void quitter() { System.out.println("Programme terminé!"); } } // Les classes d'objets class Pharmacie1 { // une pharmacie c'est une liste de client et // une liste de médicaments private Client[] clients;; private Medicament[] medicaments; public Pharmacie1(Client[] cs, Medicament[] ms) { clients = cs; medicaments = ms; } public Client[] getClients() { return this.clients; } public Medicament[] getMedicaments() { return this.medicaments; } /** * Permet à un client d'acheter un médicament. * si le client est connu de la pharmacie, son crédit * va diminuer en fonction de son paiement. * Le stock associé au médicament va diminuer */ public void achat() { Client client = this.lireClient(); Medicament medicament = this.lireMedicament(); double paiement = lirePaiement(); int quantite = lireQuantite(); if (quantite <= medicament.getStock()) { medicament.diminuerStock(quantite); client.augmenterCredit((medicament.getPrix() * quantite) - paiement); } else { System.out.println("Achat Impossible. Quantité insuffisante"); } } /** * Permet à la pharmacie de s'approvisionner en un * médicament connu. */ public void approvisionnement() { Medicament medicament = this.lireMedicament(); System.out.println("Donner la Quantité : "); int quantite = GestionPharmacie.scanner.nextInt(); medicament.augmenterStock(quantite); } /** * Affichage des stocks et des crédits de la pharmacie */ public void affichage() { System.out.println("Affichage des stocks"); for (int i = 0; i < medicaments.length; i++) { System.out.println("Stock du médicament " + medicaments[i].getNom() + " :" + medicaments[i].getStock()); } System.out.println("Affichage des crédits"); for (int i = 0; i < clients.length; i++) { System.out.println("Crédit du client " + clients[i].getNom() + " :" + clients[i].getCredit()); } } /** * Retourne l'objet Client associé à un nom (String) * Le nom est lu et redemandé tant qu'il ne correspond * pas au nom d'un client connu de la pharmacie */ public Client lireClient() { String nom; boolean trouve = false; Client c = null; System.out.println("Nom du client?:"); do { nom = GestionPharmacie.scanner.nextLine(); for (int i = 0; (!trouve && i < clients.length); i++) { if ((clients[i].getNom()).equals(nom)) { trouve = true; c = clients[i]; } } if (!trouve) { System.out.println("Client inconnu. Veuilliez recommencer"); } } while (!trouve); return c; } /** * Retourne l'objet Medicament associé à un nom (String) * Le nom est lu et redemandé tant qu'il ne correspond * pas au nom d'un médicament connu de la pharmacie */ public Medicament lireMedicament() { String nom; boolean trouve = false; Medicament m = null; System.out.println("Nom du medicament?:"); do { nom = GestionPharmacie.scanner.nextLine(); for (int i = 0; (!trouve && i < medicaments.length); i++) { if ((medicaments[i].getNom()).equals(nom)) { trouve = true; m = medicaments[i]; } } if (!trouve) { System.out.println("Médicament inconnu. Veuilliez recommencer"); } } while (!trouve); return m; } static double lirePaiement() { System.out.println("quel est le montant du paiement?"); return GestionPharmacie.scanner.nextDouble(); } static int lireQuantite() { System.out.println("quelle est la quantité achetée?"); return GestionPharmacie.scanner.nextInt(); } } class Client { // Un client est caractérisé par son nom et un crédit. private String nom = ""; private double credit = 0.0; public Client(String nom, double credit) { this.nom = nom; this.credit = credit; } public void augmenterCredit(double montant) { credit = credit + montant; } public void diminuerCredit(double montant) { credit = credit - montant; } public double getCredit() { return credit; } public String getNom() { return nom; } } class Medicament { // un médicament a un nom, un prix et une quantité en stock private String nom; private double prix; private int stock; public Medicament(String nom, double prix, int stock) { this.nom = nom; this.prix = prix; this.stock = stock; } public void augmenterStock(int quantite) { stock = stock + quantite; } public void diminuerStock(int quantite) { stock = stock - quantite; } public int getStock() { return stock; } public double getPrix() { return prix; } public String getNom() { return nom; } } |
Les tableaux
Exercice 2 : Programmation
Soit le programme Java suivant:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class ProgBoolean { boolean a[]={true, false, true, false}; boolean b[]={true, true, false, false}; static void afficher(boolean[] x){ ... } static boolean[] non(boolean[] x){ ... } static boolean[] et(boolean[] x, boolean[] y) { ... } static boolean reduireEt(boolean[] x){ ... } public static void main(String[] args) { ... } } |
QUESTION
1. Ecrire la méthode afficher qui prend un tableau de booléen et affiche son contenu de manière à ce que afficher(a) produise le résultat suivant: {vrai, faux, vrai, faux}
Note: on fera attention aux blancs et aux espaces avant et après la virgule, et avant l'accolade.
2. Ecrire le code de la méthode non qui prend un tableau de booléen en argument et retourne un tableau de booléens inverses (opération logique 'non'). Donnez le résultat de afficher(non(a)).
3. Ecrire le code de la méthode et qui prend deux tableaux de booléens de même taille, effectue une opération de et logique sur chacun de ces éléments pris deux à deux et retourne un tableau de booléens contenant les résultats. On vérifiera que ces deux tableaux ont bien la même taille et on affichera un message d'erreur dans le cas contraire. Mathématiquement, le résultat ri = xi et yi, "i compris entre 0 et le nombre d'élément des tableaux x et y. Donnez le résultat de afficher(et(a,b)) et celui de afficher(non(et(a,b))).
Ecrire le code de la méthode reduireEt qui prend un tableau de booléen x et retourne un booléen qui est le et logique de tous les éléments de x. Mathématiquement, le résultat r de cette méthode est égal à x1 & x2 &.. & xn où n est le nombre d'éléments du tableau et '&' représente l'opération logique et.
J. Ferber
Question 1.
On considère l'instruction essai(); qui est l'appel d'une méthode d'objet. Qu'est-ce qui est vrai ?
- (a) l'instruction est invalide si on n'utilise pas
this.
- (b) elle est toujours valide;
- (c) elle est valide si elle apparaît dans une méthode d'objet de la même classe,
- (d) elle est invalide parce qu'elle est sans argument,
- (e) elle n'est pas valide parce qu'il n'y a pas d'objet appelant.
Question 2. Quelles sont les affirmations vraies parmi les suivantes ?
(a) une classe peut contenir à la fois des méthodes statiques et des méthodes d'objets,
(b) seules des classes sans attributs peuvent contenir des méthodes statiques,
(c) seules des classes utilisateur peuvent contenir des méthodes statiques
(d) Si une classe contient des méthodes statiques, elle ne peut contenir des méthodes d'objet.
Question 3. Une méthode publique statique peut toujours être appelée en préfixant l'appel
(a) du nom de la classe
(b) du nom d'un objet de la classe
(c) this
(d) sans préfixe.
Question 4. Une classe Exemple a les deux constructeurs
Exemple(int a)
Exemple(float f, char c)
Qu'elles sont les déclaration correctes parmi les suivantes ?
(a) Exemple e = new Exemple();
(b) Exemple e = new Exemple(7);
(c) Exemple e = new Exemple(3.1,'A');
(d) Exemple e = new Exemple(7, 'a');
Question 5. Une méthode qui lève une exception en utilisant throw doit contenir une bloc catch pour traiter cette exception.
(a) vrai,
(b) faux.
Question 6. On suppose que Beta dérive de Alpha et Gamma dérive de Beta. Dans un appel d'une méthode de profil void methode(Object p) l'argument passé à methode peut être
(a) de type Alpha, Beta, Gamma ou Object,
(b) Objectet Alpha seulement,
(c) Gamma et Beta seulement.
Question 7. On considère le programme que voici:
class Exemple {
public boolean b = true;
public boolean set(boolean x) {
x = !x ;
return (x == b);
}
public static void main(String[] args) {
Exemple ex = new Exemple();
ex.b = ex.set(ex.b);
System.out.println(ex.b);
}
}
(a) le programme imprime true.
(b) le programme imprime false.
Question 8. On considère le programme suivant:
class Point {
int x, y;
public Point(int xx, int yy) { x = xx; y = yy; }
public void change(Point p) { p.x += x; p.y += y; }public static void main(String[] args) {
Point a = new Point(2, 3), b = new Point(5, 10);
a.change(b);
}
}
Quel est le résultat ?
(a) a et b sont inchangés.
(b) seul a est changé
(c) seul b est changé
(d) a et b sont changés.
Question 9. Une classe Beta dérive d'une classe Alpha. Les deux classes ont une méthode public boolean estIl(). On considère le fragment de programme
Beta b = new Beta();
Alpha a = b;
if ( a.estIl() ) ...
Qu'est-ce qui est vrai ?
(a) la méthode de la classe Alpha est appelée parce que Java utilise la liaison dynamique
(b) la méthode de la classe Beta est appelée parce que Java utilise la liaison dynamique
(c) la méthode de la classe Alpha est appelée parce que a est de type Alpha
(d) l'appel n'est pas valable parce que le compilateur ne sait pas déterminer laquelle des méthodes appeler.
Question 10. On considère la classe suivante.
public class X {
int x = 10;
public X() { x = 20; }
public int getX() { return x; }
}
Que se passe-t-il avec l'instruction que voici:
System.out.println( new X().getX() );
(a) Ne compile pas
(b) Compile mais lève une exception à l'exécution
(c) Affiche 10
(d) Affiche 20
(e) Boucle indéfinimen
