Devoir Surveillé de Conception orientée objet et programmation Java
Ce devoir surveillé porte sur la conception orientée objet et la programmation Java. Il évalue les compétences en compréhension de code Java, en héritage, en encapsulation, ainsi qu’en conception et implémentation de classes selon un cahier des charges précis, incluant la gestion d’exceptions. QCM / QUESTIONS DE COUR QUESTION 1 Combien d’instances de la classe A crée le code suivant ?
D'après le document Devoir Surveillé de Conception orientée objet et programmation Java
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.
Document source
Programming, Object-Oriented Design, Java · PDF · 4 pages · 2018
Afficher l'aperçu du document
Ce devoir surveillé porte sur la conception orientée objet et la programmation Java. Il évalue les compétences en compréhension de code Java, en héritage, en encapsulation, ainsi qu’en conception et implémentation de classes selon un cahier des charges précis, incluant la gestion d’exceptions.
QCM / QUESTIONS DE COUR
QUESTION 1
Combien d’instances de la classe A crée le code suivant ?
A x,u,v;
x=new A();
A y=x;
A z=new A();
Analyse :
- La déclaration
A x,u,v;ne crée pas d’instances, elle déclare simplement des références. x = new A();crée une instance de A.A y = x;ne crée pas d’instance, y référence la même instance que x.A z = new A();crée une nouvelle instance de A.
Au total, deux instances de la classe A sont créées.
Réponse : D. Deux
QUESTION 2
Quel est le résultat de l'exécution du programme suivant ?
public class ClasseA {
public void affiche() {
System.out.println("je suis un objet de ClasseA");
}
}
class ClasseB extends ClasseA {
public void affiche() {
super.affiche();
System.out.println("je suis un objet de ClasseB");
}
}
public class ClasseTest {
public void main(String[] args) {
ClasseA b = new ClasseB();
b.affiche();
}
}
Analyse :
- La variable
best de typeClasseAmais référence un objet de typeClasseB. - La méthode
affiche()est appelée surb. En Java, la méthode appelée est celle de l’objet réel (polymorphisme). - La méthode
affiche()deClasseBest donc exécutée. - Dans cette méthode,
super.affiche()appelle la méthodeaffiche()deClasseA, affichant "je suis un objet de ClasseA". - Ensuite, la ligne suivante affiche "je suis un objet de ClasseB".
Le résultat affiché est donc :
je suis un objet de ClasseA
je suis un objet de ClasseB
Réponse : Le programme affiche :
je suis un objet de ClasseA
je suis un objet de ClasseB
QUESTION 3
Choisissez la bonne ou les bonnes réponses :
- A. Une classe peut implémenter plusieurs interfaces mais doit étendre une seule classe
- B. Une classe peut implémenter plusieurs classes mais doit étendre une seule interface
- C. Une classe peut implémenter plusieurs classes et peut étendre plusieurs interfaces
- D. Une classe doit, impérativement, implémenter une seule interface et étendre une seule classe
Analyse :
- En Java, une classe peut implémenter plusieurs interfaces.
- Une classe ne peut pas implémenter une classe (ce n’est pas syntaxiquement correct).
- Une classe ne peut étendre qu’une seule classe (héritage simple).
- Elle peut implémenter zéro, une ou plusieurs interfaces.
Donc la bonne réponse est :
A. Une classe peut implémenter plusieurs interfaces mais doit étendre une seule classe
QUESTION 4
Qui peut accéder et modifier la variable name dans la classe suivante ?
package test;
public class Target {
String name = "hello";
}
Analyse :
- L’attribut
nameest déclaré sans modificateur d’accès, donc il a le niveau d’accès "package-private" (accessible uniquement dans le même paquetage). - Donc, seules les classes du paquetage
testpeuvent accéder et modifiername. - Ni les classes en dehors du paquetage, ni les classes héritant de
Targeten dehors du paquetage ne peuvent y accéder.
La bonne réponse est :
C. n’importe quelles classes dans le paquetage test
PROBLÈME
1ère Question
Développer la classe Citoyen avec les attributs, constructeurs, getters/setters, méthode equals et méthode toString.
Attributs :
int cinString nomString prenom
Constructeurs :
- Constructeur par défaut (sans paramètres)
- Constructeur paramétré (avec paramètres pour initialiser les attributs)
Getters et setters pour l’attribut cin (les autres sont supposés implémentés).
Méthode equals(Object obj) : deux citoyens sont égaux si leur nom et leur cin sont identiques.
Méthode toString() : affiche les caractéristiques du citoyen.
public class Citoyen {
private int cin;
private String nom;
private String prenom;
// Constructeur par défaut
public Citoyen() {
this.cin = 0;
this.nom = "";
this.prenom = "";
}
// Constructeur paramétré
public Citoyen(int cin, String nom, String prenom) {
this.cin = cin;
this.nom = nom;
this.prenom = prenom;
}
// Getter pour cin
public int getCin() {
return cin;
}
// Setter pour cin
public void setCin(int cin) {
this.cin = cin;
}
// equals : deux citoyens sont égaux si nom et cin sont identiques
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Citoyen other = (Citoyen) obj;
return this.cin == other.cin && this.nom.equals(other.nom);
}
// toString : affiche les caractéristiques
@Override
public String toString() {
return "Citoyen [cin=" + cin + ", nom=" + nom + ", prenom=" + prenom + "]";
}
}
Réponse : La classe Citoyen est développée comme ci-dessus.
2ème Question
Implémenter la classe CitoyenExpatrie avec ses attributs, constructeur paramétré et méthode toString().
Analyse :
- La classe
CitoyenExpatriehérite probablement deCitoyen(ceci est implicite dans le sujet). - Elle possède les attributs de
Citoyenplus ses propres attributs (non précisés dans le texte, donc on suppose qu’il faut reprendre les attributs hérités). - Le constructeur paramétré doit initialiser tous les attributs.
- La méthode
toString()doit afficher les caractéristiques, en incluant celles héritées.
Implémentation possible :
public class CitoyenExpatrie extends Citoyen {
private String paysResidence;
// Constructeur paramétré
public CitoyenExpatrie(int cin, String nom, String prenom, String paysResidence) {
super(cin, nom, prenom);
this.paysResidence = paysResidence;
}
// toString
@Override
public String toString() {
return super.toString() + ", paysResidence=" + paysResidence;
}
}
Remarque : Le sujet ne donne pas explicitement les attributs spécifiques à CitoyenExpatrie. Ici, on a ajouté un attribut plausible paysResidence pour illustrer la réponse. Si le sujet ne précise rien, on ne peut pas répondre plus précisément.
3ème Question
Développer la classe Pays avec :
- Ses attributs
- Le constructeur paramétré
- La méthode
void ajouterCitoyen(Citoyen c)(max 800 citoyens) - La méthode
void afficherStat()qui affiche le nombre de citoyens locaux et expatriés - La méthode
void supprimer(Citoyen c)qui supprime un citoyen - La méthode
boolean estTunisien(Citoyen c)qui retourne true si le citoyen expatrié est tunisien, false sinon - La méthode
afficherNbTunisiens()qui retourne le nombre de citoyens tunisiens expatriés et déclenche une exceptionNbMaxTunisienssi ce nombre dépasse 150 - La classe d’exception
NbMaxTunisiens
Développement détaillé :
Attributs
- Un tableau ou un tableau dynamique (mais Collections interdites) de
Citoyenpour stocker les citoyens. - Un entier pour compter le nombre actuel de citoyens.
public class Pays {
private Citoyen[] citoyens;
private int nbCitoyens;
private final int MAX_CITOYENS = 800;
// Constructeur paramétré
public Pays() {
citoyens = new Citoyen[MAX_CITOYENS];
nbCitoyens = 0;
}
// Ajouter un citoyen
public void ajouterCitoyen(Citoyen c) {
if (nbCitoyens < MAX_CITOYENS) {
citoyens[nbCitoyens] = c;
nbCitoyens++;
} else {
System.out.println("Nombre maximum de citoyens atteint.");
}
}
// Afficher statistiques
public void afficherStat() {
int nbLocaux = 0;
int nbExpatries = 0;
for (int i = 0; i < nbCitoyens; i++) {
if (citoyens[i] instanceof CitoyenExpatrie) {
nbExpatries++;
} else {
nbLocaux++;
}
}
System.out.println("Nb Citoyens locaux= " + nbLocaux + " // Nb Citoyens expatries= " + nbExpatries);
}
// Supprimer un citoyen
public void supprimer(Citoyen c) {
for (int i = 0; i < nbCitoyens; i++) {
if (citoyens[i].equals(c)) {
// Décaler les éléments suivants vers la gauche
for (int j = i; j < nbCitoyens - 1; j++) {
citoyens[j] = citoyens[j + 1];
}
citoyens[nbCitoyens - 1] = null;
nbCitoyens--;
break;
}
}
}
// Vérifier si un citoyen expatrié est tunisien
public boolean estTunisien(Citoyen c) {
if (c instanceof CitoyenExpatrie) {
CitoyenExpatrie ce = (CitoyenExpatrie) c;
// Supposons que le pays d'origine est déterminé par le nom ou un attribut (non précisé)
// Ici, on suppose que le nom "Tunisien" est dans le nom (hypothèse faute de précision)
return ce.getNom().equalsIgnoreCase("Tunisien");
}
return false;
}
// Afficher nombre de tunisiens expatriés et déclencher exception si > 150
public int afficherNbTunisiens() throws NbMaxTunisiens {
int count = 0;
for (int i = 0; i < nbCitoyens; i++) {
if (citoyens[i] instanceof CitoyenExpatrie) {
if (estTunisien(citoyens[i])) {
count++;
}
}
}
if (count > 150) {
throw new NbMaxTunisiens("Nombre maximum de tunisiens expatriés dépassé");
}
return count;
}
}
Classe d’exception
public class NbMaxTunisiens extends Exception {
public NbMaxTunisiens(String message) {
super(message);
}
}
Remarques :
- La méthode
estTunisienrepose sur une hypothèse faute d’informations précises sur la façon d’identifier un citoyen tunisien. - La suppression décale les éléments du tableau pour éviter les trous.
- La gestion du tableau respecte la contrainte d’interdire les Collections.
Réponse : La classe Pays et l’exception NbMaxTunisiens sont développées comme ci-dessus.
Méthode
Ce devoir récompense une bonne maîtrise des concepts fondamentaux de la programmation orientée objet en Java : compréhension des références et instances, héritage, polymorphisme, encapsulation, et gestion des exceptions.
Il est important de :
- Analyser précisément le code donné, notamment la différence entre déclaration de variables et création d’instances.
- Comprendre le polymorphisme et l’appel des méthodes dans une hiérarchie de classes.
- Respecter les règles de syntaxe et de sémantique Java, notamment pour l’héritage et l’implémentation des interfaces.
- Implémenter les classes en respectant les spécifications, notamment les constructeurs, méthodes
equalsettoString. - Gérer les collections d’objets sans utiliser les classes de la bibliothèque Java Collections, en manipulant des tableaux classiques.
- Gérer les exceptions personnalisées pour contrôler des contraintes métier.
- Présenter un code clair avec des étapes de raisonnement visibles, notamment pour les méthodes de suppression et de comptage.
Les erreurs à éviter sont :
- Confondre déclaration et instanciation d’objets.
- Ne pas utiliser le polymorphisme correctement (exemple : appeler une méthode sur une référence de type parent).
- Ne pas respecter la signature des méthodes héritées ou surchargées.
- Utiliser des Collections alors qu’elles sont interdites.
- Ne pas gérer correctement les exceptions ou ne pas les déclarer.
Commentaires
Aucun commentaire pour le moment. Posez la première question.