ISCAE – 2ème année ID/IG/RT – POO Série III
Exercice 1. Personne, Skieur et Slalommeur
1. Ecrire une classe Personne ayant pour attributs privés une chaîne de caractères nom et un entier
age.
Ecrire un constructeur prenant en arguments une chaîne de caractères et un entier.
Ecrire les accesseurs correspondant aux attributs.
Ecrire une méthode toString permettant d'afficher le nom d'une personne suivi de son age entre
parenthèses (exemple :Mohamed Salem (36 ans)).
Ecrire une méthode main pour tester la classe Personne.
2. Ecrire une classe Skieur, sous-classe de la classe Personne, ayant pour attribut privé
supplémentaire un booléen forfait (qui est vrai si le skieur a un forfait, faux sinon).
Essayer de compiler la classe personne, sans rien ajouter d'autre. Que se passe-t-il ?
Ecrire un constructeur prenant en arguments une chaîne nom, un entier age, et un booléen forfait.
Ce constructeur devra commencer par : super(nom,age) pour construire d'abord la partie Personne
de l'objet Skieur. Que se passe-t-il à la compilation si vous mettez en commentaire la ligne
contenant l'appel à super ?
Ecrire les accesseurs correspondant à l'attribut forfait.
Ecrire une méthode toString qui affichera une phrase comme :Mohamed Salem (36 ans) a un
forfait (ou n'a pas de forfait suivant le cas). On peut faire appel à la méthode toString de la classe
Personne en écrivant : super.toString()
Ecrire une méthode main pour tester la classe Skieur.
3. Dans la méthode toString de Skieur, que se passe-t-il si vous essayez de récupérer le nom et l'âge
du skieur sans passer par les accesseurs de la classe Personne ? Modifier les attributs de Personne
pour qu'ils soient protected : que se passe-t-il maintenant dans la méthode toString ? Modifiez aussi
l'attribut de la classe Skieur pour qu'il soit protected.
4. Ecrire une classe Slalommeur, sous-classe de la classe Skieur, ayant pour attribut supplémentaire
temps de type double (représentant son temps à l'épreuve de slalom).
Ecrire un constructeur prenant en argument un Skieur. Ce constructeur servira à inscrire des
skieurs à l'épreuve de slalom, et initialisera leur temps à 0. Si le skieur n'a pas de forfait, le
constructeur affichera un message indiquant :Mohamed Salem doit se procurer un forfait avant le
début de l'épreuve.
Ecrire les accesseurs correspondant à l'attribut temps. L'accesseur permettant de régler le temps
devra vérifier que le slalommeur a un forfait ; dans le cas contraire, l'attribut temps est réglé à 0 car
sans forfait on ne peut pas participer !
Ecrire une méthode toString qui affichera une phrase comme : Mohamed Salem (36 ans) : 188
secondes (ou bien si le skieur n'a pas de forfait : Mohamed Salem ne peut pas participer sans forfait
!).
Ecrire une méthode main pour tester la classe Slalommeur.
Exercice 2. Médiathèque
Une médiathèque souhaite gérer les livres, CD et cassettes vidéos disponibles au prêt.
Chaque article disponible au prêt possède une cote, servant à le repérer dans la médiathèque (ex :
AZ123).
Un livre est caractérisé par son titre, son auteur, son nombre de pages.
Un CD est caractérisé par son titre, son interprète, sa durée.
Une vidéo est caractérisée par son titre, son réalisateur, une liste d'acteurs, et sa durée.
1. Ecrire une classe Article ayant pour attributs protected une chaîne de caractères cote, une chaîne
de caractère titre, et un booléen emprunte indiquant si l'article est emprunté (true) ou disponible
(false). Ecrire le constructeur, et les accesseurs.
2. Ecrire trois classes Livre, CD, et Video dérivant de la classe Article et permettant de stocker
chacun des trois types d'objets de la médiathèque. Ecrire dans ces trois classes les constructeurs et
accesseurs de chaque classe, ainsi que les trois méthodes toString() permettant l'affichage des
propriétés de chaque article.
3. Ecrire une classe Mediatheque ayant pour attribut un tableau d'Article et un entier nbArticles.
Dans cette classe, on écrira les méthodes suivantes : ajouterArticle(Article a),
emprunterArticle(String cote), rendreArticle(String cote), getNbArticles(), listerArticles(),
voirDetailArticle(String cote). On pourra aussi écrire une méthode Article getArticle(String cote)
qui renvoie l'article de cote donnée.
On écrira également une méthode main() permettant de tester les différentes méthodes de toutes
les classes.
4. Regarder la documentation de la classe ArrayList : à quoi sert cette classe, quelles sont les
méthodes que vous allez utiliser pour ajouter ou retirer des articles du "tableau" ? Ecrire une classe
MediathequeArrayList ayant pour attribut un objet de type ArrayList. Dans cette classe, on écrira les
mêmes méthodes qu'à la question précédente, et une méthode main() permettant de tester les
différentes méthodes de toutes les classes.
Exercice 3. Jeu des cibles
Il s'agit d'écrire en JAVA une application de jeu. Ce jeu consiste à déplacer un curseur (à l'aide de la
souris, par exemple) et à détruire des cibles qui apparaissent dans une fenêtre sur l'écran.
Le repère associé à une fenêtre a son origine dans le coin supérieur gauche, l'axe des y est orienté
vers le bas (repère indirect). La figure qui suit montre par exemple une fenêtre de jeu de taille
800x600 pixels (points).
Dans cet exercice, on ne s'intéressera qu'à la programmation des cibles. On supposera donc que la
fenêtre de jeu est représentée par un objet de classe FenêtreDeJeu qui propose deux méthodes :
• public int getLargeur() qui retourne la largeur (en nombre de pixels) de la
fenêtre.
• public int getHauteur() qui retourne la hauteur (en nombre de pixels) de la
fenêtre.
Une cible est définie par une position (couple de coordonnées entières) et une forme, qui peut être
soit un cercle soit un carré. Si la cible est circulaire sa position donne le centre du cercle la
matérialisant, si la cible est carrée sa position indique les coordonnées de son coin supérieur gauche.
L'utilisateur peut déplacer le curseur de tir. Lorsque le curseur se trouve à l'intérieur d'une cible
(carré ou cercle) et que l'utilisateur enclenche le tir la cible est atteinte. Le comportement d'une cible
lorsqu'elle est atteinte varie selon la nature de la cible.
Pour représenter les différents types de cibles les classes suivantes sont définies :
La classe Cible
La classe Cible définit ce qui est commun à toutes les cibles :
Les informations (attributs ou variables d'instance) associées à une cible sont :
• la position de la cible définie par un couple (x,y) de coordonnées entières.
• une référence fenetre de type FenêtreDeJeu , référence vers l'objet représentant la
fenêtre dans laquelle la cible est affichée.
La position initiale est fixée lors de la création d'une cible (les valeurs de l'abscisse et de l'ordonnée
de la position sont passées en paramètre du constructeur de la classe Cible ainsi que la référence
de l'objet FenêtreDeJeu dans lequel le jeu se déroule).
Les opérations (méthodes) définies pour une cible sont :
• public boolean contient(int x, int y)
qui permet de tester si un point (le curseur) est à l'intérieur de la cible. Cette méthode prend
en paramètres un couple x, y de coordonnées entières et retourne une valeur booléenne (true
si le point (x,y) est à l'intérieur de la cible, false sinon).
• deux méthodes public int getCx(), public int getCy()qui retournent
respectivement l'abscisse, l'ordonnée de la cible.
• public void choc()
c'est la méthode qui est appelée lorsque la cible est effectivement atteinte. Son action dépend
bien sur du type de la cible.
La classe CibleCirculaire
La classe CibleCirculaire définit comme son nom l'indique des cibles de forme circulaire.
Lorsqu'elles sont atteintes par un tir du joueur, les cibles circulaires ont le comportement suivant
(comportement implémenté dans la méthode choc()) :
la cible voit son rayon diminuer d'une unité (un pixel). Lorsque ce rayon devient nul, la cible est
repositionnée de façon aléatoire dans la fenêtre de jeu et le rayon reprend sa valeur initiale (valeur
qu'avait le rayon de la cible avant d'être atteinte pour la première fois et fixée lors à la création de la
cible).
La classe CibleCirculaireMobile
La classe CibleMobileCirculaire est une sous-classe de la classe CibleCirculaire.
Cette classe va permettre la gestion d'un nouveau type de cibles : les cibles mobiles. Ces cibles ont
un mouvement de translation horizontal et se déplacent d'un bord à l'autre de la fenêtre (lorsque la
cible rencontre un des bords de la fenêtre, elle "rebondit" et son déplacement se fait alors dans le
sens opposé).
La classe CibleCirculaireMobile enrichit la classe CibleCirculaire d'une nouvelle
variable d'instance :
• un entier dx, qui désigne de combien de pixels la cible doit être déplacée lors de l'appel de
la méthode deplacer (voir ci-dessous). Cette variable d'instance est fixée lors de la
création de la cible (donnée en paramètre du constructeur).
D'autre part, une nouvelle méthode est associée à ce type de cibles :
• public void deplacer()
lors de l'appel à cette méthode, la cible est déplacée de dx pixels suivant l'axe des abscisses
(on peut remarquer que si dx>0, la cible se déplace vers la droite et que si dx<0, la cible se
déplace vers la gauche). Lorsque la cible rencontre un des bords verticaux de la fenêtre, elle
rebondit et son déplacement se fait alors en sens inverse.
Enfin, les cibles circulaires mobiles ont un comportement particulier lorsqu'elles sont atteintes par
le tir du joueur (méthode choc()). En effet, non seulement leur rayon diminue d'une unité (avec
les mêmes conséquences que pour les cibles fixes de type Cible si le rayon devient nul), mais en
plus, leur sens de déplacement s'inverse (comme lorsqu'elles rencontrent un des bords verticaux de
la fenêtre).
Question 1) Donner une description synthétique des différentes classes nécessaires à la
représentation des cibles.
Question 2) Ecrire le code JAVA de la classe Cible. Définir ses variables d'instance (attributs),
écrire son constructeur et ses différentes méthodes.
Question 3) Ecrire le code JAVA de la classe CibleCirculaire. Définir ses variables
d'instance (attributs), écrire son constructeur et ses différentes méthodes.
(Lors d'un choc, pour calculer la nouvelle position de la cible on fera appel à la fonction
random() de la classe Math (Math.random() retourne un double tiré au hasard dans
l'intervalle [0..1]).
Question 4) Ecrire le code JAVA de la classe CibleCirculaireMobile. Définir ses variables
d'instance (attributs), écrire son constructeur et ses différentes méthodes.
Question 5) Dans le fragment de code suivant, indiquer pour chaque instruction si celle-ci est
valide ou non (c.a.d. si s'elle sera acceptée ou non par le compilateur JAVA) en justifiant chacune
de vos réponses.
CibleCirculaireMobile c1 = new
CibleCirculaire(125,340,20,laFenetre);
Cible c2 = new CibleCirculaireMobile(100,100,10,-
3,laFenetre);
if (c2.contient(105,107))
c2.choc();
c2.deplacer();
On supposera que laFenetre est une variable qui contient une référence valide vers un objet de
classe FenetreDeJeu.
Les paramètres 125,340,20 pour la CibleCirculaireMobile sont respectivement
l'abscisse et l'ordonnée de sa position initiale et son rayon initial.
Les paramètres 100,100,10,-3 pour la CibleCirculaireMobile sont respectivement
l'abscisse et l'ordonnée de sa position initiale, son rayon initial et la valeur de son déplacement
élémentaire.
Question 6) Le programme principal de l'application est donné par l'algorithme suivant :
Creer la Fenetre de jeu
Créer un EC ensemble de cibles dans cette fenêtre
(les cibles sont générées de manière alétoire)
tantque la partie n'est pas finie faire
dessiner les cibles
récuperer la position x,y du curseur du joueur
pour chaque cible dans EC
si la cible contient le curseur
appliquer à la cible le "traitement de choc"
si la cible est une cible mobile
deplacer la cible
fintantque
Ecrire les instructions Java correspondant aux parties de l'algorithme ci-dessus écrites en gras,
sachant que pour gérer l'ensemble de cibles on décide d'utiliser un objet de la classe ArrayList
définie dans java.util. Cette classe se comporte comme un tableau dynamique. Elle permet de
permet de construire dynamiquement une liste d'objets, chaque objet présent dans la liste pouvant
être accédé directement par un index (0 pour le premier élément de la liste, 1 pour le deuxième,
etc....). Contrairement aux tableaux il n'est pas nécessaire de spécifier la taille d'un ArrayList, de
plus celle-ci croit dynamiquement au fur et à mesure que la liste des éléments qu'il contient
augmente.