Conception par objet et programmation Java
Partie 1 : Choix multiples Question 1 - Ordre d'exécution des constructeurs Bonne réponse : C. 123 Justification : En Java, lorsqu'on instancie une classe enfant (ici Three ), le constructeur de la classe courante fait systématiquement appel au constructeur de sa classe parente avant d'exécuter son propre code.
D'après le document Conception par 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 · PDF · 8 pages · 2015
Afficher l'aperçu du document
Partie 1 : Choix multiples
Question 1 - Ordre d'exécution des constructeurs
Bonne réponse : C. 123
Justification :
En Java, lorsqu'on instancie une classe enfant (ici Three), le constructeur de la classe courante fait systématiquement appel au constructeur de sa classe parente avant d'exécuter son propre code. S'il n'y a pas d'appel explicite via super(...), le compilateur insère un appel implicite super() vers le constructeur sans paramètre de la classe mère.
Ainsi, lors de l'instruction new Three() ; :
- Le constructeur de
Threeest appelé, mais avant d'imprimer "3", il appelle implicitementsuper()versTwo. - Le constructeur de
Twoest appelé, mais avant d'imprimer "2", il appelle implicitementsuper()versOne. - Le constructeur de
Oneest exécuté (car il hérite deObject). Il affiche 1. - Le contrôle revient au constructeur de
Twoqui affiche 2. - Le contrôle revient au constructeur de
Threequi affiche 3.
Le résultat final est donc l'affichage séquentiel de "123".
Question 2 - Héritage et constructeur par défaut
Bonne réponse : D. Compilation échoue en raison d'une erreur dans la ligne 7.
Justification :
La classe parente Person possède uniquement un constructeur paramétré (public Person(String nm)). Elle ne possède pas de constructeur par défaut (sans paramètre), car dès lors qu'un constructeur est défini explicitement par le développeur, Java ne génère plus le constructeur par défaut.
À la ligne 7, le constructeur de la classe fille Employee ne fait aucun appel explicite à super(...). Le compilateur tente donc d'insérer un appel implicite super() ;. Puisque le constructeur par défaut n'existe pas dans Person, le compilateur lève une erreur.
Pour corriger ce code, il faudrait écrire à la ligne 7 : public Employee(String id) { super("Nom par défaut"); empID = id; } ou bien ajouter un constructeur sans paramètre dans la classe Person.
Question 3 - Références et indexation des tableaux
Bonne réponse : B. Ligne 3 affiche la valeur 3.
Justification :
En Java, les tableaux sont des objets. À la ligne 2 (int y[] = x ;), le tableau y ne devient pas une copie du tableau x, mais une nouvelle référence pointant vers le même espace mémoire que x.
De plus, l'indexation des tableaux commence à 0.
Le tableau contient les valeurs : {1, 2, 3, 4, 5}.
- L'index 0 contient 1.
- L'index 1 contient 2.
- L'index 2 contient 3.
L'instruction y[2] accède donc à la troisième case du tableau, qui contient bien la valeur 3.
Partie 2 : Conception par objet et programmation Java
Avant d'entamer l'écriture des classes, il est important de noter une consigne clé : Les Getters et les setters ne sont à implémenter que si leur demande est explicite. Pour respecter cette règle et permettre à la classe Equipe d'accéder aux attributs (comme le numéro du joueur) sans utiliser de getters, nous allons déclarer les attributs avec la visibilité par défaut (package-private). Ils seront ainsi accessibles par les autres classes du même package, dont la classe Equipe.
I. Implémentation de la classe Membre
Le sujet exige uniquement un constructeur paramétré, des getters/setters exclusifs pour l'identifiant, et une méthode equals prenant spécifiquement un objet Membre en paramètre (il s'agit d'une surcharge de la méthode de la classe Object).
public class Membre {
// Visibilité par défaut pour permettre l'accès depuis Equipe sans getters
int identifiant;
String nom;
// Uniquement un constructeur paramétré
public Membre(int identifiant, String nom) {
this.identifiant = identifiant;
this.nom = nom;
}
// Getters et Setters seulement pour l’attribut identifiant
public int getIdentifiant() {
return identifiant;
}
public void setIdentifiant(int identifiant) {
this.identifiant = identifiant;
}
public String toString() {
return "Membre [identifiant=" + identifiant + ", nom=" + nom + "]";
}
// Surcharge de la méthode equals (prend Membre en paramètre comme demandé)
public boolean equals(Membre m) {
if (m == null) {
return false;
}
if (this == m) {
return true;
}
return (this.identifiant == m.identifiant && this.nom.equals(m.nom));
}
}
II. Implémentation des classes Joueur et Entraineur
Les deux classes héritent de Membre et doivent faire appel à super() pour initialiser les attributs de la classe mère.
public class Joueur extends Membre {
int numero;
public Joueur(int identifiant, String nom, int numero) {
super(identifiant, nom);
this.numero = numero;
}
public String toString() {
return "Joueur [identifiant=" + identifiant + ", nom=" + nom + ", numero=" + numero + "]";
}
}
public class Entraineur extends Membre {
int anneesExperience;
public Entraineur(int identifiant, String nom, int anneesExperience) {
super(identifiant, nom);
this.anneesExperience = anneesExperience;
}
public String toString() {
return "Entraineur [identifiant=" + identifiant + ", nom=" + nom + ", anneesExperience=" + anneesExperience + "]";
}
}
III. Implémentation de la classe Equipe
Nous devons modéliser une équipe avec un tableau de Membre d'une taille maximale de 30. Par souci de complétude technique afin que le code compile, nous allons inclure les classes d'exceptions personnalisées que le code doit lever.
// Déclaration des exceptions personnalisées demandées
class EquipeNonValideException extends Exception {
public EquipeNonValideException(String message) {
super(message);
}
}
class TransfertException extends Exception {
public TransfertException(String message) {
super(message);
}
}
public class Equipe {
int identifiant;
String nom;
Membre[] membres;
int nbMembres; // Compteur pour suivre le nombre actuel de membres
public Equipe(int identifiant, String nom) {
this.identifiant = identifiant;
this.nom = nom;
this.membres = new Membre[30]; // Capacité maximale de 30
this.nbMembres = 0;
}
// 1. Méthode rechercher
public int rechercher(Membre membre) {
if (membre == null) {
return -1;
}
for (int i = 0; i < nbMembres; i++) {
// Utilise la méthode equals définie dans Membre
if (membres[i].equals(membre)) {
return i;
}
}
return -1;
}
// 2. Méthode ajouter
public void ajouter(Membre membre) {
if (nbMembres < 30) { // Vérifie la capacité maximale
if (rechercher(membre) == -1) { // Vérifie l'absence de doublon
membres[nbMembres] = membre;
nbMembres++;
}
}
}
// 3. Méthode supprimer
public void supprimer(Membre membre) {
int indice = rechercher(membre);
if (indice != -1) {
// Décalage des éléments vers la gauche pour combler le vide
for (int i = indice; i < nbMembres - 1; i++) {
membres[i] = membres[i + 1];
}
membres[nbMembres - 1] = null; // Nettoyage de la dernière case
nbMembres--;
}
}
// 4. Méthode toString (Affiche l'id, le nom de l'équipe et UNIQUEMENT les joueurs)
public String toString() {
String resultat = "Equipe " + nom + " (ID: " + identifiant + ")\nListe des joueurs :\n";
for (int i = 0; i < nbMembres; i++) {
// L'opérateur instanceof permet de filtrer uniquement les objets de type Joueur
if (membres[i] instanceof Joueur) {
resultat += membres[i].toString() + "\n";
}
}
return resultat;
}
// 5. Méthode valider
public void valider() throws EquipeNonValideException {
int nbEntraineurs = 0;
for (int i = 0; i < nbMembres; i++) {
if (membres[i] instanceof Entraineur) {
nbEntraineurs++;
}
}
if (nbEntraineurs == 1) {
System.out.println("Equipe valide");
} else {
throw new EquipeNonValideException("L'équipe n'est pas valide (elle a " + nbEntraineurs + " entraineur(s)).");
}
}
// 6. Méthode afficherNumeros (Uniquement pour les joueurs)
public void afficherNumeros() {
for (int i = 0; i < nbMembres; i++) {
if (membres[i] instanceof Joueur) {
Joueur j = (Joueur) membres[i];
// L'attribut numero est accessible car défini sans modificateur private
System.out.println("Numéro : " + j.numero);
}
}
}
// 7. Méthode transfererJoueur
public void transfererJoueur(Joueur joueur, Equipe e1, Equipe e2) throws TransfertException {
if (e1.rechercher(joueur) == -1) {
throw new TransfertException("Transfert impossible");
}
e1.supprimer(joueur);
e2.ajouter(joueur);
}
}
Méthode
Pour aborder efficacement un sujet d'examen de programmation orientée objet en Java :
- Lisez toujours les contraintes générales en premier. Ici, la règle "Les Getters et les setters ne sont à implémenter que si leur demande est explicite" est primordiale. En entreprise, on encapsule tout en
privateavec des accesseurs systématiques. Dans le contexte de cet examen, le professeur vérifie votre capacité à respecter un cahier des charges strict. Passer par la visibilité par défaut est une astuce technique pertinente pour obéir à la contrainte sans bloquer votre code. - Maîtrisez les constructeurs. Comprendre l'appel implicite à
super()(comme vu dans les questions 1 et 2) est l'un des pièges les plus fréquents en Java. Rappelez-vous que tout constructeur d'une classe fille invoque, avant toute chose, le constructeur de sa mère. - Identifiez le polymorphisme et le filtrage d'objets. L'utilisation de l'opérateur
instanceofest souvent la clé lorsqu'on manipule un tableau polymorphique (ici, un tableau deMembrecontenant à la fois desJoueuret desEntraineur). - Réutilisez vos méthodes. Pour la méthode
ajouteretsupprimer, faites toujours appel à votre propre méthoderechercherplutôt que de recréer une bouclefor. Cela montre au correcteur que vous comprenez le principe de la réutilisabilité du code.
Commentaires
Aucun commentaire pour le moment. Posez la première question.