Ce document académique propose la correction complète de l'examen de deuxième session NFA 002 - Programmation JAVA, conçu spécifiquement pour les étudiants universitaires. Il se structure autour d'un questionnaire à choix multiples (QCM) détaillé, où chaque réponse est rigoureusement expliquée pour faciliter l'apprentissage et la compréhension des erreurs.
Le contenu s'étend ensuite à des questions libres de réflexion et à une section pratique de programmation, illustrant des concepts fondamentaux tels que l'orientation objet, le polymorphisme, la gestion des exceptions, les threads et les design patterns, offrant ainsi une vision exhaustive des compétences attendues en Java.
Examen Programmation JAVA 2ème session 2011-2012 -Concours QCM
Télécharger PDFCorrection de l'Examen Deuxième Session 2011-2012 NFA 002 - Programmation JAVA
QCM (35 points)
Question 1 : En Java, la classe Hashtable<K,V> est une classe de définition d'une collection d'éléments, dont les éléments sont de type V et l'indice d'accès est un entier K qui va de 0 à size()-1.
Réponse donnée : OUI
Explication : Ceci est incorrect. En Java, la classe Hashtable<K,V> stocke des paires clé-valeur. K représente la clé (l'identifiant unique) et V la valeur. Les clés ne sont pas nécessairement des entiers, ni des indices allant de 0 à size()-1. Cette description est plus appropriée pour une collection basée sur un index comme un tableau ou une ArrayList.
Question 2 : En Java, la classe Collections permet de trier les éléments de n'importe quelle collection (classe qui implémente l'interface List<T>) grâce à la méthode Collections.sort(List<T>) et si la classe des éléments de la collection implémente l'interface Comparable.
Réponse donnée : NON
Explication : Ceci est partiellement incorrect. La méthode Collections.sort(List<T>) utilise bien l'interface Comparable pour un tri naturel des éléments de la liste. Cependant, il existe une surcharge Collections.sort(List<T>, Comparator<? super T>) qui permet de trier une liste avec un ordre personnalisé, sans que les éléments n'implémentent pas nécessairement Comparable.
Question 3 : JAVA est un langage orienté objet dont les fichiers sources sont directement interprétables.
Réponse donnée : NON
Explication : Ceci est correct. Les fichiers sources Java (.java) sont d'abord compilés en bytecode (.class), qui est ensuite interprété par la machine virtuelle Java (JVM). Ils ne sont pas directement interprétables comme certains langages de script.
Question 4 : Une classe abstraite est une classe qui peut contenir des méthodes abstraites (sans implémentation). Dans ce cas, il est à la charge des classes dérivées d'implémenter ces méthodes abstraites.
Réponse donnée : OUI
Explication : Ceci est correct. Une classe abstraite peut contenir des méthodes concrètes (avec implémentation) et des méthodes abstraites. Les classes concrètes qui en héritent doivent impérativement implémenter toutes les méthodes abstraites, sauf si elles sont elles-mêmes déclarées abstraites.
Question 5 : Soit le code correct suivant :
public class A extends B
{
private int attr_A;
public A()
{
attr_A = 10;
attr_B = "TOTO";
C.attr_C = 100;
}
}
Options :
- attr_B peut être un attribut privé de B
- attr_C peut être un attribut statique et public de C
- attr_C peut être un attribut statique et privé de C
Réponse donnée : attr_B peut être un attribut privé de B
Explication : Si le code fourni est correct et que la classe A hérite de B, l'attribut attr_B ne peut pas être privé dans la classe B, car une classe dérivée (A) ne peut pas accéder directement aux membres privés de sa classe parente (B). Pour que attr_B = "TOTO"; soit valide dans A, attr_B devrait être au minimum protégé (protected) ou public dans B. En revanche, "attr_C peut être un attribut statique et public de C" serait une condition valide pour que C.attr_C = 100; fonctionne.
Question 6 : Soit deux classes B et C qui héritent d'une classe abstraite A. Les classes B et C peuvent utiliser par héritage les méthodes publiques non abstraites de la classe A.
Réponse donnée : OUI
Explication : Ceci est correct. Les classes dérivées héritent des méthodes publiques (et protégées) de leur classe parente, qu'elle soit abstraite ou non, à condition que ces méthodes ne soient pas abstraites.
Question 7 : Une classe qui contient au moins une méthode abstraite doit être déclarée abstraite.
Réponse donnée : NON
Explication : Ceci est incorrect. Une classe qui contient au moins une méthode abstraite *doit* être déclarée abstraite. C'est une règle fondamentale en Java. Si elle n'est pas déclarée abstraite, le compilateur générera une erreur.
Question 8 : En Java, on déclare un tableau de la manière suivante T[] tab = new T[100].
Options :
- T peut être une classe abstraite
- T peut être une interface
- T ne peut pas être de types primitifs
Réponse donnée : T peut être une classe abstraite
Explication : Ceci est correct. En Java, il est possible de créer un tableau d'objets d'une classe abstraite (par exemple, RendezVous[]). Ces tableaux pourront contenir des instances de classes concrètes qui héritent de cette classe abstraite. Il est également possible de créer des tableaux d'interfaces (par exemple, Runnable[]), ainsi que des tableaux de types primitifs (par exemple, int[]).
Question 9 : En JAVA, si une classe C implémente plusieurs interfaces I1, I2, I3
Options :
- La classe C ou les classes dérivées de C doivent implémenter toutes les méthodes de toutes les interfaces I1, I2, I3
- La classe C ou les classes dérivées de C doivent implémenter toutes les méthodes de I1 mais pas de I2 et I3
Réponse donnée : La classe C ou les classes dérivées de C doivent implémenter toutes les méthodes de toutes les interfaces I1, I2, I3
Explication : Ceci est correct. Si une classe implémente une ou plusieurs interfaces, elle doit fournir une implémentation pour toutes les méthodes abstraites déclarées dans ces interfaces, à moins que la classe elle-même ne soit déclarée abstraite.
Question 10 : En JAVA, une interface peut contenir des attributs qui sont statiques et publics.
Réponse donnée : OUI
Explication : Ceci est correct. En Java, tous les attributs déclarés dans une interface sont implicitement public static final (des constantes).
Question 11 : En JAVA, une interface permet de :
Options :
- créer une méthode générique dont le traitement utilise des méthodes de l'interface
- créer des classes abstraites
Réponse donnée : créer une méthode générique dont le traitement utilise des méthodes de l'interface
Explication : Ceci est correct. Les interfaces sont fondamentales pour la conception de méthodes génériques et le polymorphisme en Java, permettant aux méthodes d'opérer sur des objets de différentes classes tant qu'elles implémentent l'interface commune. Créer des classes abstraites est le rôle de l'instruction abstract class, pas par interface.
Question 12 : La déclaration d'une méthode suivante : public void traitement(String s) throws MyException précise que la méthode est susceptible de propager l'exception MyException.
Réponse donnée : OUI
Explication : Ceci est correct. La clause throws dans la signature d'une méthode indique qu'elle est susceptible de propager (ne pas gérer directement) une exception vérifiée (checked exception) du type spécifié ou un de ses sous-types.
Question 13 : Soit le code suivant qui ajoute un Individu dans un tableau :
public void ajouter(String nom) throws Exception
{
Individu ind=null;
try
{
ind = rechercher(nom);
}
catch(NonTrouveException ex)
{
tab[n++] = ind;
}
}
La méthode rechercher retourne l'exception NonTrouveException si le nom de l'individu n'est pas trouvé.
Options :
- si l'individu que l'on veut ajouter n'est pas trouvé alors la méthode retourne l'exception NonTrouveException
- si l'individu que l'on veut ajouter n'est pas trouvé et le tableau n'est pas plein alors l'individu est ajouté au tableau
- Si l'individu que l'on veut ajouter n'est pas trouvé et le tableau est plein alors la méthode retourne une exception prédéfinie Java (IndexOutOfBoundsException)
Réponse donnée : Si l'individu que l'on veut ajouter n'est pas trouvé et le tableau est plein alors la méthode retourne une exception prédéfinie Java (IndexOutOfBoundsException)
Explication : Ceci est correct. Si la méthode rechercher déclenche NonTrouveException, le bloc catch est exécuté. À ce moment, ind est toujours null. L'instruction tab[n++] = ind; tentera d'ajouter null au tableau. Si n a déjà atteint la limite du tableau, une ArrayIndexOutOfBoundsException (un sous-type de IndexOutOfBoundsException) sera levée, car l'accès à tab[n] serait hors des bornes.
Question 14 : Soit le code suivant :
try
{
System.out.println("AAA");
call();
System.out.println("BBB");
}
catch(MyException ex)
{
System.out.println("DDD");
}
catch(Exception ex)
{
System.out.println("CCC");
}
avec la méthode call qui déclenche l'exception UneAutreException. Ce code affiche :
Réponse donnée : AAA CCC
Explication : Ceci est correct. Le code affiche "AAA". Ensuite, la méthode call() déclenche UneAutreException. Étant donné qu'il n'y a pas de bloc catch spécifique pour UneAutreException et qu'elle n'est probablement pas un sous-type de MyException (sauf spécification contraire), le flux de contrôle passe au bloc catch(Exception ex) car toutes les exceptions héritent de la classe Exception. Par conséquent, "CCC" est affiché.
Question 15 : En JAVA, un package est une classe qui hérite de Package et permet de créer une collection à travers les méthodes pack() et unpack().
Réponse donnée : OUI
Explication : Ceci est incorrect. En Java, un package est un mécanisme de regroupement et d'organisation des classes et des interfaces, offrant un espace de noms et contrôlant la visibilité. Il n'est pas une classe et ne comporte pas de méthodes pack() et unpack() pour gérer des collections. La classe java.lang.Package existe, mais elle représente les informations d'un package en cours d'exécution ; elle n'est pas le package lui-même au sens de l'organisation du code.
Question 16 : En JAVA le "package" est un design pattern qui modélise les principes de compression et de décompression des objets dans un socket (pliage/dépliage ou pack/unpack).
Réponse donnée : OUI
Explication : Ceci est incorrect. Le concept de "package" en Java est un mécanisme d'organisation du code source et des classes compilées, non un design pattern. Il ne modélise pas la compression/décompression d'objets dans un socket.
Question 17 : Le design pattern Factory est un modèle de conception de la mise en œuvre d'une communication client serveur.
Réponse donnée : OUI
Explication : Ceci est incorrect. Le design pattern Factory (ou Fabrique) est un modèle de conception créationnel qui fournit une interface pour la création d'objets dans une super-classe, mais permet aux sous-classes de modifier le type d'objets qui seront créés. Il n'est pas directement lié à la mise en œuvre de la communication client-serveur.
Question 18 : Le Singleton est un design pattern qui est une classe contenant la méthode unique public T getInstance(). À chaque appel, cette méthode retourne une instance unique de type T (ou de la classe elle-même).
Réponse donnée : OUI
Explication : Ceci est correct. Le design pattern Singleton garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à cette instance, souvent via une méthode statique getInstance(). Le type retourné serait l'instance de la classe Singleton elle-même, ou un type qu'elle implémente.
Question 19 : Le code suivant crée un descripteur de fichier dont le nom est "exemple.txt" permettant par exemple de tester si le fichier existe. File fichier; fichier = new File("exemple.txt");
Réponse donnée : OUI
Explication : Ceci est correct. Le code instancie un objet File qui représente un chemin d'accès à un fichier ou un répertoire. Il ne crée pas le fichier sur le système de fichiers, mais plutôt une abstraction de ce fichier en mémoire, sur laquelle on peut ensuite appeler des méthodes comme exists(), canRead(), etc.
Question 20 : La classe File permet de parcourir les fichiers d'un répertoire.
Réponse donnée : NON
Explication : Ceci est incorrect. La classe File en Java dispose de méthodes telles que list() et listFiles() qui permettent précisément de lister et donc de parcourir les fichiers et les sous-répertoires contenus dans un répertoire. Par conséquent, l'affirmation selon laquelle la classe File permet de parcourir les fichiers d'un répertoire est vraie.
Question 21 : On a le code suivant :
File fichier = new File("ListeDouble.bin");
FileOutputStream fos = new FileOutputStream(fichier);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(tab.length);
for(int i=0;i< tab.length;i++) dos.writeDouble( tab[i]);
dos.close();
Options :
- Ce code crée un fichier de nom 'ListeDouble.bin' contenant la liste de doubles
- Ce code crée un fichier dont les informations sont dans un format texte
- Ce code crée un fichier dont les informations sont dans un format binaire
Réponse donnée : Ce code crée un fichier dont les informations sont dans un format texte
Explication : Ceci est incorrect. Le code utilise DataOutputStream, qui est conçu pour écrire des données de types primitifs Java (comme int et double) dans un flux de sortie binaire. Par conséquent, il crée un fichier dont les informations sont dans un format binaire, et non dans un format texte.
Question 22 : La classe File ne gère que les fichiers. Pour gérer des répertoires on utilise la classe Directory.
Réponse donnée : NON
Explication : Ceci est correct. En Java, la classe File est utilisée pour représenter à la fois les fichiers et les répertoires. Il n'existe pas de classe standard Directory séparée pour la gestion des répertoires. La classe File offre des méthodes pour vérifier si un objet est un fichier ou un répertoire, pour créer des répertoires, les lister, etc.
Question 23 : La sérialisation est un service du langage Java qui permet d'écrire et de lire n'importe quel objet dans un fichier binaire (Serializable) ou un fichier texte (XML).
Réponse donnée : NON
Explication : Ceci est correct. La sérialisation Java standard (via l'interface Serializable et ObjectOutputStream) permet d'écrire et de lire l'état d'un objet *dans un format binaire*, et ce pour les objets dont la classe implémente l'interface Serializable. Elle ne gère pas directement le format texte (comme XML) sans l'aide de bibliothèques additionnelles, et ne s'applique pas à "n'importe quel objet" mais uniquement aux objets sérialisables.
Question 24 : Le code suivant est correct :
File f = new File("/etc/passwd");
System.out.println(f.exists());
System.out.println(f.canRead());
System.out.println(f.canWrite());
System.out.println(f.getLength());
File d = new File("/etc/");
System.out.println(d.isDirectory());
String[] files = d.list();
for(int i=0; i < files.length; i++)
System.out.println(files[i]);
Réponse donnée : NON
Explication : Ceci est correct. Le code contient une erreur : la méthode pour obtenir la taille d'un fichier est length() (f.length()), et non getLength(). Par conséquent, le code n'est pas correct tel quel.
Question 25 : Le package est une unité de programmation permettant de regrouper et architecturer les classes du langage Java (prédéfinies ou développées) dans des répertoires et accessibles aux autres unités de programmation (programme Java, Applet, …).
Réponse donnée : OUI
Explication : Ceci est correct. Les packages sont essentiels en Java pour l'organisation du code, la gestion des espaces de noms et le contrôle de l'accès aux classes.
Question 26 : Un package est un répertoire qui ne peut pas contenir d'autres répertoires.
Réponse donnée : OUI
Explication : Ceci est incorrect. Un package en Java correspond à un répertoire dans le système de fichiers, et il peut tout à fait contenir d'autres sous-répertoires, qui correspondent à des sous-packages. C'est ainsi que sont organisées les hiérarchies de packages en Java (par exemple, java.util.concurrent où 'concurrent' est un sous-package de 'util').
Question 27 : L'option –d de la commande javac permet de générer les fichiers .class dans un autre répertoire que celui contenant les fichiers .java.
Réponse donnée : NON
Explication : Ceci est incorrect. L'option -d de la commande javac est précisément utilisée pour spécifier le répertoire de destination où les fichiers .class compilés doivent être placés. Cela permet de séparer les fichiers sources (.java) des fichiers compilés (.class). Par conséquent, l'affirmation est vraie.
Question 28 : En JAVA, un thread est une JVM qui s'exécute en parallèle de la JVM dans laquelle le thread a été créé.
Réponse donnée : OUI
Explication : Ceci est incorrect. En Java, un thread est une unité d'exécution légère qui s'exécute *au sein de la même machine virtuelle Java (JVM)*. Tous les threads d'une application partagent le même espace mémoire et les ressources de la JVM. Un thread n'est pas une JVM indépendante.
Question 29 : Soit le thread définit de la manière suivante : public class MonThread extends Thread {.... . } et MonThread t = new MonThread(); On démarre le thread t de la manière suivante :
Options :
t.run()t.start()new Thread(t).start()
Réponse donnée : t.run()
Explication : Ceci est incorrect. Pour démarrer un nouveau thread d'exécution et que le code de la méthode run() s'exécute dans ce nouveau thread, il faut impérativement appeler la méthode t.start(). L'appel direct à t.run() exécute simplement le code de la méthode run() dans le thread courant, sans créer de nouveau thread.
Question 30 : La classe A hérite de B qui hérite de C. C est une classe abstraite qui implémente une interface I. A et B ne sont pas des classes abstraites.
Options :
- C peut implémenter une partie des méthodes de l'interface I
- A et B doivent à elles deux implémenter toutes les méthodes de I qui n'ont pas été implémentées par C
- A ne peut pas implémenter des méthodes de l'interface I
Réponse donnée 1 : A et B doivent à elles deux implémenter toutes les méthodes de I qui n'ont pas été implémentées par C
Explication 1 : Ceci est incorrect. Puisque C est une classe abstraite qui implémente l'interface I, elle peut laisser des méthodes de I non implémentées. Comme B est la première classe concrète qui hérite de C, c'est la classe B qui doit impérativement implémenter toutes les méthodes abstraites restantes de l'interface I (et de C) pour être concrète. La classe A, héritant de B, bénéficiera de ces implémentations.
Réponse donnée 2 : A ne peut pas implémenter des méthodes de l'interface I
Explication 2 : Ceci est incorrect. La classe A, étant une classe concrète qui hérite d'une hiérarchie implémentant l'interface I, non seulement *peut* implémenter ou surcharger les méthodes de l'interface I, mais elle *doit* le faire si elles n'ont pas été implémentées par B ou C (ce qui n'est pas le cas ici puisque B est concrète).
Question 31 : Soit le code suivant :
class MonRunnable extends Toto implements Runnable
{
public void run() { // traitement }
}
Pour créer et démarrer le thread :
Options :
new Thread(new MonRunnable ()).start();MonRunnable p = (MonRunnable)(new Thread()); p.start()MonRunnable p = new MonRunnable (); Thread q = new Thread(p); q.start();
Réponse donnée : new Thread(new MonRunnable ()).start();
Explication : Ceci est correct. La classe MonRunnable implémente l'interface Runnable. Pour créer et démarrer un thread, une instance de MonRunnable doit être passée au constructeur de Thread, puis la méthode start() de l'objet Thread doit être appelée. La troisième option présentée (MonRunnable p = new MonRunnable (); Thread q = new Thread(p); q.start();) est également une manière correcte de créer et démarrer ce thread, équivalente à la première.
Question 32 : Un tableau Java peut contenir des types primitifs.
Réponse donnée : OUI
Explication : Ceci est correct. Les tableaux Java peuvent contenir des types primitifs (comme int, char, boolean, etc.) ainsi que des références d'objets.
Question 33 : Une collection polymorphe est une instance d'une classe P<T> contenant des objets dont les classes peuvent être différentes et toutes ces classes héritent de la classe abstraite T:
Réponse donnée : NON
Explication : Ceci est incorrect. Une collection polymorphe est précisément une collection capable de contenir des objets de types différents, tant que ces types partagent un ancêtre commun (une classe mère ou une interface). L'exemple donné, où les classes héritent d'une classe abstraite T, est un cas d'usage courant du polymorphisme.
Question 34 : En JAVA, la classe RuntimeException qui hérite de la classe Exception permet de déclencher une exception pour laquelle il n'est pas utile de déclarer comme devant être propagé.
Réponse donnée : OUI
Explication : Ceci est correct. Les exceptions qui héritent de RuntimeException sont appelées « unchecked exceptions ». Le compilateur Java ne force pas leur déclaration (via la clause throws) ni leur gestion (via un bloc try-catch). Elles sont souvent utilisées pour signaler des erreurs de programmation qui devraient être évitées.
Question 35 : La sérialisation est une interface prédéfinie de JAVA qui permet d'écrire et lire les objets dans un fichier.
Réponse donnée : NON
Explication : Ceci est correct. La sérialisation n'est pas une interface en tant que telle. C'est un *mécanisme* du langage Java. L'interface java.io.Serializable est une *interface de marquage* (marker interface) qui indique qu'une classe peut être sérialisée, mais elle ne contient aucune méthode pour écrire ou lire les objets. Ce sont les classes ObjectOutputStream et ObjectInputStream qui gèrent concrètement l'écriture et la lecture des objets sérialisés.
Questions libres
Question 1 : Expliquez à quoi sert l'interface.
En Java, une interface est un contrat qui définit un ensemble de méthodes abstraites (et à partir de Java 8, des méthodes par défaut et statiques) ainsi que des constantes (implicitement public static final). Elle est utilisée pour atteindre l'abstraction et le polymorphisme, permettant de définir des comportements communs que différentes classes peuvent implémenter. Cela facilite la création de traitements génériques et de collections polymorphes, où les objets peuvent être manipulés via l'interface, indépendamment de leur classe concrète.
Question 2 : Quels sont les deux moyens permettant de créer un thread ? Pourquoi utiliser l'un ou l'autre ?
Il existe deux principales manières de créer un thread en Java :
- En étendant la classe
java.lang.Thread: La classe doit hériter deThreadet surcharger la méthoderun(). Pour démarrer le thread, on appelle la méthodestart()de l'instance de la classe. - En implémentant l'interface
java.lang.Runnable: La classe doit implémenter l'interfaceRunnableet fournir une implémentation pour la méthoderun(). Ensuite, une instance de cette classe est passée au constructeur de la classeThread, et la méthodestart()de l'objetThreadest appelée.
Le choix entre les deux dépend principalement de la flexibilité requise. L'implémentation de Runnable est généralement préférée, car elle permet à la classe de base d'hériter d'une autre classe tout en définissant un comportement de thread, ce que l'extension de Thread ne permettrait pas en raison de l'absence d'héritage multiple en Java.
Question 3 : À quoi est utilisé le design pattern Factory ? Quel est son principe fondamental ?
Le design pattern Factory (ou Fabrique) est un modèle de conception créationnel dont l'objectif est de créer des objets sans spécifier la classe exacte de l'objet qui sera créé. Il est utilisé pour encapsuler la logique de création d'objets. Son principe fondamental est de fournir une interface ou une méthode abstraite pour la création d'objets dans une super-classe, mais de laisser les sous-classes décider quelle classe instancier. Ceci rend le système plus flexible et moins couplé, car le client n'a pas besoin de connaître les classes concrètes des objets qu'il utilise. La Factory peut retourner des objets qui partagent une interface ou une classe parente commune, permettant ainsi un traitement polymorphe.
Deuxième PARTIE : PROGRAMMATION
Problème
Le code suivant présente une implémentation simple d'un agenda en Java, utilisant le polymorphisme et les classes abstraites pour gérer différents types de rendez-vous.
import java.util.*;
// Classe de définition du programme principal qui teste l'agenda
public class Probleme
{
public static void main(String args[])
{
// Création d'un agenda
Agenda agenda = new Agenda();
// Création de plusieurs rendez-vous, de classes différentes
// et tous ces rendez-vous sont ajoutés dans l'agenda
RdvJournalier rdv1 = new RdvJournalier("2012-09-01", "9h30", "10h00", "Passer prendre Jean à l'aéroport");
RdvPeriodique rdv2 = new RdvPeriodique("2012-08-01", "2012-12-01", "HEBDO", "10h30", "12h30", "Point sur le développement");
RdvPeriodique rdv3 = new RdvPeriodique("2012-07-01", "2012-12-01", "MENSUEL", "10h30", "12h30", "Point sur le développement");
// Parce que tous ces rendez-vous héritent de la classe abstraite RendezVous,
// on peut utiliser la même méthode pour les ajouter dans l'agenda
agenda.ajouter(rdv1);
agenda.ajouter(rdv2);
agenda.ajouter(rdv3);
// Affichage de l'agenda
agenda.afficher();
}
}
// Un agenda est une collection de rendez-vous.
// La classe RendezVous est une classe abstraite ce qui permet d'ajouter
// des rendez-vous de classes différentes du moment que ces classes héritent
// de la classe abstraite RendezVous.
public class Agenda
{
// Collection polymorphe de rendez-vous
public ArrayList<RendezVous> rdvs;
// Constructeur qui crée la collection à vide
public Agenda()
{
rdvs = new ArrayList<RendezVous>();
}
// Ajout d'un rendez-vous. Le rendez-vous en paramètre est une instance de
// n'importe quelle classe qui hériterait de RendezVous.
public void ajouter(RendezVous rdv)
{
rdvs.add(rdv);
}
// Affiche tous les rendez-vous de la collection en appelant la méthode
// d'affichage de chacun des objets. En fonction de sa classe d'appartenance,
// chaque objet appellera la méthode afficher de sa classe.
public void afficher()
{
trier();
for(RendezVous rdv : rdvs)
{
System.out.println("----------------------");
rdv.afficher();
}
}
// Méthode de tri des rendez-vous de l'agenda
public void trier()
{
Collections.sort(rdvs,new ComparerRdv());
}
}
// Classe de comparaison des rendez-vous utilisée pour trier
// les rendez-vous de l'agenda.
class ComparerRdv implements Comparator<RendezVous>
{
public int compare(RendezVous o1,RendezVous o2)
{
return( o1.getDateRdv().compareTo(o2.getDateRdv()) );
}
}
// Classe commune de définition d'un rendez-vous.
// La classe est abstraite car la méthode afficher est abstraite.
public abstract class RendezVous
{
// Les attributs communs à tous les rendez-vous.
// Tout rendez-vous a une heure de début, de fin et un texte.
protected String heureDebut;
protected String heureFin;
protected String texte;
// Constructeur
public RendezVous(String heureDebut,
String heureFin,
String texte)
{
this.heureDebut = heureDebut;
this.heureFin = heureFin;
this.texte = texte;
}
// Ce sera aux classes réelles qui héritent de RendezVous de faire
// l'affichage du rendez-vous.
// C'est pour cela que les attributs de cette classe sont protected (afin
// que les classes réelles accèdent aux attributs).
abstract public void afficher();
// Retourne la date du rendez-vous.
abstract public String getDateRdv();
}
// Classe de définition d'un rendez-vous journalier.
// La classe hérite de la classe abstraite RendezVous.
public class RdvJournalier extends RendezVous
{
// Date du rendez-vous.
public String date;
// Constructeur
public RdvJournalier(String date,
String heureDebut,
String heureFin,
String texte)
{
// Initialisation des attributs de la classe héritée.
super(heureDebut,heureFin,texte);
this.date = date;
}
// Affichage du rendez-vous journalier.
public void void afficher()
{
System.out.println("Date du rdv : " + date);
System.out.println("Heure de debut : " + heureDebut);
System.out.println("Heure de fin : " + heureFin);
System.out.println("Texte : " + texte);
}
// Retourne la date du rendez-vous.
public String getDateRdv()
{
return date;
}
}
// Classe de définition d'un rendez-vous périodique.
// La classe hérite de la classe abstraite RendezVous.
public class RdvPeriodique extends RendezVous
{
// Date du premier rendez-vous.
public String dateDebut;
// Date de fin de la période.
public String dateFin;
// Type de période : MENSUEL ou HEBDO.
public String periode;
// Constructeur
public RdvPeriodique(String dateDebut,
String dateFin,
String periode,
String heureDebut,
String heureFin,
String texte)
{
super(heureDebut,heureFin,texte);
this.dateDebut = dateDebut;
this.dateFin = dateFin;
this.periode = periode;
}
// Affichage du rendez-vous périodique.
public void afficher()
{
System.out.println("Date du premier rdv : " + dateDebut);
System.out.println("Heure de debut : " + heureDebut);
System.out.println("Heure de fin : " + heureFin);
System.out.println("Texte : " + texte);
System.out.println("Periode : " + periode);
}
// Retourne la date du rendez-vous.
public String getDateRdv()
{
return dateDebut;
}
}
FAQ
1. Qu'est-ce qu'une interface en Java ?
Une interface en Java est un contrat qui définit un ensemble de méthodes abstraites et de constantes (public static final). Elle permet de réaliser l'abstraction et le polymorphisme, en spécifiant un comportement commun que différentes classes peuvent implémenter, favorisant ainsi la réutilisation du code et une architecture flexible.
2. Comment créer un thread en Java ?
Il existe deux méthodes principales pour créer un thread en Java : soit en étendant la classe java.lang.Thread et en surchargeant sa méthode run(), soit en implémentant l'interface java.lang.Runnable et en fournissant une implémentation pour sa méthode run(). L'implémentation de Runnable est souvent préférée car elle permet à la classe de base d'hériter d'une autre classe, contournant l'absence d'héritage multiple en Java.
3. Qu'est-ce que le design pattern Factory ?
Le design pattern Factory (ou Fabrique) est un modèle de conception créationnel qui vise à créer des objets sans exposer la logique d'instanciation au client. Il fournit une interface générique pour la création d'objets, permettant aux sous-classes de décider quelle classe concrète instancier. Son principe est de découpler la création d'objets de leur utilisation, rendant le système plus flexible et maintenable.