Contrôle 2 de mars 2011

Transcription

Contrôle 2 de mars 2011
Programmation objet UFR Sciences – L3 Informatique – 2010/2011 Durée : 2h00 Les trois questions sont indépendantes les unes des autres et peuvent être traitées dans n’importe quel ordre. Le barème est donné à titre indicatif. Exercice 1 – Questions de cours [6 points] Répondre en 2 lignes maximum. 1. Que signifie « this » en Java ? De quel type est‐il ? This référence l’instance courante Il a le type de la classe dans laquelle il est utilisé. 2. Quelles sont les différences entre une interface et une classe en Java ? Une interface est un type purement abstrait : méthodes publiques et abstraites, champs constants Une classe peut implémenter plusieurs interfaces et hériter d’une seule classe 3. Quelle particularité ont les membres déclarés static ? Ils sont communs à toutes les instances de la classe dans laquelle ils sont déclarés. Les méthodes, comme les champs, sont utilisés directement à partir de la classe, sans nécessiter la création d’un objet. 4. Que signifient les mots‐clés « public », « protected » et « private » ? « public » dénote les membres et classes accessibles à partir de n’importe quelle classe. « protected » dénote les membres accessibles à partir de n’importe quelle classe fille ou située dans le même paquetage. « private » dénote les membres et classes accessibles uniquement à partir du bloc de déclaration de classe dans lequel ils sont déclarés. 5. Quelle est la différence entre "redéfinir" et "surcharger" une méthode ? La surcharge consiste à utiliser le même nom pour désigner deux méthodes ou références distinctes, les méthodes sont alors distinguées par une signature différente La redéfinition consiste à définir dans une classe fille, une méthode déclarée (et définie) dans une classe mère. La signature doit être strictement identique. 6. Quel est l'avantage d'une ArrayList par rapport à un tableau ? Une ArrayList a une taille dynamique alors que la taille d’un tableau est déterminée définitivement lors de la construction. Exercice 2 – Modèle objet [8 points] L'échange massif de fichiers mp3 est, aux yeux de l'industrie musicale, une catastrophe (et une bénédiction
pour les amateurs de musique ;-)). Les gros acteurs du marché (Sony, Universal, BMG, ...) envisagent toutes
les solutions pour stopper les pirates en herbe. Une solution consiste à vendre les chansons à l'unité sur le
net, à bas prix. Ainsi une poignée d'entreprises telles OD2 (France) et MusicNet (USA) se spécialisent dans
la distribution online de musique numérique. Leurs clients sont la Fnac, Amazon.com, Tiscali, ...
OD2 vous demande de faire un modèle de classes de leur base de fichiers mp3. Les artistes produisent des
œuvres : des disques et des chansons. Une œuvre a un genre (ex: Jazz, Techno, R'nB), une date de
distribution et un titre. Chaque disque est composé d'au moins 2 chansons. Une chanson peut être présente
sur plusieurs disques. Il est aussi fréquent que plusieurs artistes s'associent pour la réalisation d'une chanson,
ou même d'un disque entier.
a) Quel modèle proposeriez-vous aux responsables d'OD2 ? Déclarez en Java les classes et méthodes de
ce modèle. Si vous ne savez pas faire le Java, faites un diagramme UML.
class Artiste {
ArrayList<Oeuvre> oeuvres = new ArrayList<Oeuvre>() ;
void produit(Oeuvre oeuvre) {
this.oeuvres.add(oeuvre) ;
}
}
abstract class Oeuvre {
Date dateDistribution ;
String titre ;
Oeuvre(Date date, String titre) {
this.dateDistribution = date ;
this.titre = titre ;
}
abstract Genre getGenre() ;
}
class Chanson extends Oeuvre{
Genre genre ;
Chanson(Genre genre, Date date, String titre) {
super(date, titre) ;
this.genre = genre ;
}
Genre getGenre() {
return this.genre ;
}
}
class Disque extends Oeuvre{
ArrayList<Chanson> chansons = new ArrayList<Chanson>() ;
Disque(Chanson c1, Chanson c2, Date date, String titre) {
super(date, titre) ;
this.chansons.add(c1) ;
this.chansons.add(c2) ;
}
void add(Chanson c) {
chansons.add(c) ;
}
Genre getGenre() {
// par exemple, +s solutions possibles, cf. getListeGenres() question c)
return new GenreComposite(getListeGenres());
}
}
class GenreComposite extends Genre { }
b) Comment faire pour garantir que tous les disques possèdent au moins deux chansons ? Ecrire le code
Java correspondant.
Tous les constructeurs de la classe Disque doivent avoir deux chansons en paramètres. Il ne doit pas
y avoir de constructeur qui n’a pas au moins ces deux paramètres => Pas de constructeur par défaut !
On peut aussi passer une liste en paramètre et tester qu’il y a au moins deux disques.
ArrayList<Chanson> chansons = new ArrayList<Chanson>() ;
Disque(Chanson c1, Chanson c2 …) {
chansons.add(c1) ;
chansons.add(c2) ;
}
c) Ecrire en Java la méthode int getNombreGenres() de la classe Disque qui calcule le
nombre de genres différents utilisés dans les chansons d’un disque.
Pour que la méthode « contains » fonctionnent correctement, il faut redéfinir les méthodes
equals(Object) : boolean et hashCode() : int de la classe Genre !
class Disque {
ArrayList<Chanson> chansons = new ArrayList<Chanson>() ;
private ArrayList<Genre> getListeGenres() {
ArraysList<Genre> genres = new ArrayList<Genre>() ;
for(Chanson c : chansons) {
if ( !genres.contains(c.getGenre())) genres.add(c.getGenre()) ;
}
return genres;
}
int getNombreGenres() {
return getListeGenres().size() ;
}
}
d) Ecrire en Java la méthode Genre[] getGenres() de la classe Disque qui calcule l'ensemble
des genres utilisés dans les chansons de ce disque. Les doublons ne sont pas acceptés.
class Disque {
ArrayList<Chanson> chansons = new ArrayList<Chanson>() ;
private ArrayList<Genre> getListeGenres() { /* cf. c) */
Genre[] getGenres() {
return getListeGenres().toArray() ;
}
}
Exercice 3 – Exceptions [6 points] On veut modéliser en Java le fonctionnement simplifié d’un cinéma (cf. figure ci‐contre) qui ne propose qu’un seul film mais dispose de plusieurs salles. Une Salle peut accueillir un nombre fixe (n) de Spectateur. Lorsqu’un spectateur arrive, on le place dans la dernière salle disponible. Si la salle est pleine, alors on ouvre une nouvelle salle. Un Cinema peut ouvrir autant de salles (*) qu’il le souhaite (oui ce n’est pas réaliste !). On ne cherche pas à modéliser tout le problème mais seulement la gestion des exceptions. a) Définir en Java une classe SallePleineException qui sera levée lorsque le cinéma essaye de placer un spectateur dans une salle pleine. Cette exception DOIT connaître le spectateur qui a déclenché sa levée. class SallePleineException extends Exception {
Spectateur spectateur ;
SallePleinException(Spectateur s) {
super("le Spectateur :"+s+" n’a pas de place");
}
this.spectateur = s ;
}
}
b) Ecrire la méthode ajouterSpectateur(Spectateur) de la classe Salle qui ajoute un spectateur et lève l’exception SallePleineException lorsque la salle est pleine. Vous choisirez la structure de donnée qui vous semble être la plus appropriée (tableau, liste, …). Tout dépend de la structure de donnée utilisée. Comme le nombre de place est figé, on choisit un tableau. Quelle que soit la solution retenue, il faut avoir une capacité et un nombre de spectateur. class Salle {
private Spectateur[] spectateurs ;
private int nbSpectateurs = 0 ;
Salle (int capacité) {
this.spectacteurs = new Spectateur[capacité] ;
}
void ajouterSpectateur(Spectateur s) throws SallePleineException {
if(nbSpectateurs == spectateurs.length)
throw new SallePleineException(s) ;
spectateurs[nbSpectateurs] = s ;
nbSpectateurs ++ ;
}
}
c) Ecrire la méthode placer(Spectateur) de la classe Cinema qui ajoute un spectateur à la dernière salle disponible. Si l’exception est levée, alors on créé une nouvelle salle dans laquelle on place le spectateur. Tout dépend encore de la structure de donnée utilisée. Comme le nombre de salle n’est pas borné, on choisit un LinkedList. (On aurait pu prendre un ArrayList). class Cinema {
private LinkedList<Salle> salles = new LinkedList<Salle>() ;
Cinema () {
this.salles.addLast(new Salle(100)); // Au moins une salle
}
void placer(Spectateur s) {
try {
salles.getLast().add(s) ;
} catch(SallePleineException e) {
salles.addLast(new Salle(100)) ;
this.placer(s) ; // Appel récursif (par exemple)
}
}
}
La classe Spectateur est supposée exister. 

Documents pareils