Gestion factures achats/ventes – Implémentation Java : constructeurs et méthodes pour Article & LigneFacture
Exercice 1 : Gestion des factures achats et ventes Question 1 - Déclaration des attributs de la classe Article Le diagramme de classes et le code fourni dans l'énoncé indiquent deux attributs pour la classe Article . L'énoncé contient quelques erreurs de frappe (comme Strring ) que nous devons corriger pour avoir un code Java valide. De plus, il est conseillé d'initialiser la variable statique.
D'après le document Gestion factures achats/ventes – Implémentation Java : constructeurs et méthodes pour Article & LigneFacture
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Programming, Math, etc. · PDF · 6 pages · 2017
Afficher l'aperçu du document
Exercice 1 : Gestion des factures achats et ventes
Question 1 - Déclaration des attributs de la classe Article
Le diagramme de classes et le code fourni dans l'énoncé indiquent deux attributs pour la classe Article. L'énoncé contient quelques erreurs de frappe (comme Strring) que nous devons corriger pour avoir un code Java valide. De plus, il est conseillé d'initialiser la variable statique.
private static int numArt = 0;
private String libelle;
Question 2 - Constructeur de la classe Article
Le constructeur doit incrémenter le numéro de l'article de manière séquentielle et affecter le libellé. Le code source fourni dans la correction contient des erreurs de syntaxe (comme this,libelle, une minuscule à article pour le nom du constructeur, et l'utilisation de NumArt avec une majuscule). Voici le code corrigé :
public Article(String libelle) {
numArt = numArt + 1; // Ou simplement numArt++;
this.libelle = libelle;
}
Question 3 - Méthode SaisirArticle
La méthode doit permettre à l'utilisateur de saisir le libellé via le clavier. Le code de l'énoncé contient des erreurs de syntaxe majeures : System,in au lieu de System.in, sc,nextline() au lieu de sc.nextLine(), et l'abréviation S.O.P qui n'existe pas en Java. L'abréviation S.O.P correspond classiquement à System.out.println().
import java.util.Scanner;
public void SaisirArticle() {
Scanner sc = new Scanner(System.in);
System.out.println("Donner le libellé de l'article :");
this.libelle = sc.nextLine();
}
Question 4 - Constructeur de la classe LigneFacture
Ce constructeur initialise les attributs d'une ligne de facture. L'énoncé présente des virgules à la place des points pour l'utilisation de this (ex: this,article=article ;) et des points-virgules manquants. Voici la version syntaxiquement correcte :
public LigneFacture(Article article, double prix, int qte) {
this.article = article;
this.prix = prix;
this.qte = qte;
}
Question 5 - Méthode AfficherLigFacture
Cette méthode affiche les détails. À nouveau, nous devons corriger article,AfficherArticle() en article.AfficherArticle() et remplacer S.O.P par System.out.println().
public void AfficherLigFacture() {
article.AfficherArticle();
System.out.println("Le prix est " + prix);
System.out.println("La quantité est " + qte);
}
Question 6 - Accesseurs et mutateurs (getters et setters) de la classe LigneFacture
La correction de l'énoncé contient une erreur fondamentale sur les types de retour des accesseurs (get). Par exemple, public void getQte() est incorrect car un getter doit retourner la valeur de l'attribut, il ne peut donc pas être de type void. Il doit être de type int pour la quantité.
Voici le code source complet et correct pour tous les attributs (qte, article, prix) :
// Accesseurs et mutateurs pour 'qte'
public void setQte(int qte) {
this.qte = qte;
}
public int getQte() {
return qte;
}
// Accesseurs et mutateurs pour 'article'
public void setArticle(Article article) {
this.article = article;
}
public Article getArticle() {
return article;
}
// Accesseurs et mutateurs pour 'prix'
public void setPrix(double prix) {
this.prix = prix;
}
public double getPrix() {
return prix;
}
Question 7 - Déclaration de la classe abstraite Facture
L'énoncé a oublié le mot-clé class dans sa correction. Pour déclarer une classe abstraite implémentant une interface en Java, la syntaxe exacte est :
public abstract class Facture implements OperationFacture {
// Corps de la classe
}
Question 8 - Constructeur dans une classe abstraite
Oui, il est tout à fait possible de créer un constructeur pour une classe abstraite.
Utilité : Bien que l'on ne puisse pas instancier directement une classe abstraite avec le mot-clé new (ex: new Facture()), ses classes filles (comme FactureVente ou FactureAchat) feront appel à ce constructeur (via le mot-clé super()) lors de leur propre instanciation. Cela permet de centraliser et de factoriser le code d'initialisation des attributs communs, évitant ainsi la duplication de code dans les classes dérivées.
Question 9 - Méthode AfficherFacture de la classe Facture
Cette méthode doit parcourir un tableau d'objets LigneFacture. Les corrections nécessaires par rapport à l'énoncé concernent l'appel de la méthode de date (date.AfficherDate() au lieu de date,AfficherDate()) et la déclaration du type de la variable i dans la boucle for.
public void AfficherFacture() {
System.out.println("Le numéro de la facture est " + numFact);
date.AfficherDate();
for(int i = 0; i < ligneFact.length; i++) {
ligneFact[i].AfficherLigFacture();
}
}
(Note : Ce code suppose que ligneFact est un tableau de LigneFacture et que numFact, date et ligneFact sont des attributs déclarés dans la classe).
Question 10 - Méthode AfficherFacture de la classe FactureVente
Puisque FactureVente hérite de Facture, il est judicieux de réutiliser le code de la classe mère grâce au mot-clé super.
public void AfficherFacture() {
super.AfficherFacture();
client.AfficherDetailclient();
}
Question 11 - Méthode TotalFacture
Le calcul du total nécessite de sommer le produit du prix et de la quantité pour chaque ligne de facture. L'énoncé utilise la classe enveloppe Double pour le type de retour, mais un type primitif double est plus approprié ici (bien que l'auto-boxing de Java tolère les deux). Nous devons déclarer la variable i dans la boucle.
public double TotalFacture() {
double total = 0.0;
for(int i = 0; i < ligneFact.length; i++) {
total = total + (ligneFact[i].getPrix() * ligneFact[i].getQte());
}
return total;
}
Question 12 - Classe GestionFacture et méthode main
Le code fourni dans le barème correspond à du pseudo-code (SOP, M.nexInt()). Voici la traduction en un code Java parfaitement valide et exécutable, qui respecte toutes les sous-questions demandées.
import java.util.Scanner;
public class GestionFacture {
public static void main(String[] args) {
Scanner M = new Scanner(System.in);
int user;
// 1- Déclarer un tableau pouvant contenir 10 Factures
Facture[] FACT = new Facture[10];
// 2- Pour chaque facture dans le tableau :
for(int i = 0; i < FACT.length; i++) {
System.out.println("Taper 1 pour Facture Vente ou 2 pour Facture Achat :");
user = M.nextInt(); // 2.1 Demander à l'utilisateur
// 2.2 Créer une nouvelle facture vide selon le choix
if (user == 1) {
FACT[i] = new FactureVente();
} else if (user == 2) {
FACT[i] = new FactureAchat();
} else {
System.out.println("Erreur de saisie");
// Pour éviter un NullPointerException par la suite,
// on pourrait décrémenter i ou forcer une instanciation par défaut.
}
// 2.3 Saisir les informations relatives à la facture
if (FACT[i] != null) {
FACT[i].saisirFacture();
}
}
// 3- Afficher le nombre de lignes de chaque facture
for(int i = 0; i < FACT.length; i++) {
if (FACT[i] != null && FACT[i].getLigneFact() != null) {
int nbligne = FACT[i].getLigneFact().length;
System.out.println("Le nombre de lignes de la facture " + i + " est " + nbligne);
}
}
// 4- Afficher le nombre total de factures
// Utilisation de la méthode statique getNumFact() de la classe Facture
System.out.println("Le nombre total de factures est " + Facture.getNumFact());
M.close();
}
}
Exercice 2 : Questions à Choix Multiples (QCM)
Question 1 - Exécution de la classe Calculator
Réponse correcte : a) 20
Explication du cheminement :
Calculator obj = new Calculator();instancie l'objet. À ce stade, son attribut d'instancenumvaut 100.obj.calc(2);appelle la méthodecalcen passant la valeur 2 au paramètre localnum.- Dans la méthode
calc, l'instructionthis.num = num * 10;est exécutée. Ici,this.numfait référence à l'attribut d'instance de l'objet, tandis quenumfait référence au paramètre (qui vaut 2). Donc, l'attribut d'instance devient 2 × 10 = 20. obj.printNum();affiche la valeur de l'attribut d'instance, qui est désormais de 20.
Question 2 - Déclarations de classes et d'interfaces
Réponses correctes : b), d), e)
Explication des règles d'héritage en Java :
- a) est fausse :
Cest une classe abstraite. Une classe s'hérite avecextends, on ne peut pas l'implémenter avecimplements. - b) est vraie : Une classe
Fpeut implémenter une interfaceB. - c) est fausse : L'héritage multiple de classes n'est pas autorisé en Java (une classe ne peut pas utiliser
extendssur deux classesAetEsimultanément). - d) est vraie : Une classe
Fpeut hériter d'une classeE. - e) est vraie : L'implémentation multiple d'interfaces est autorisée en Java. Une classe peut implémenter
BetDen même temps.
Question 3 - Nature du langage Java
Réponses correctes : c), d)
Explication : Le code source Java (.java) est d'abord compilé en un code intermédiaire appelé bytecode (.class). Ensuite, ce bytecode est interprété (et souvent compilé à la volée via JIT) par la Machine Virtuelle Java (JVM) lors de l'exécution. Netbeans est un simple environnement de développement (IDE), le code n'a absolument pas besoin de lui pour s'exécuter.
Question 4 - Références et égalité
Sous-question 4.1 : Le programme affiche
Réponse correcte : a) 101010
Explication :
obj1est créé avecm = 10.obj2est créé avecm = 10.obj3est créé avecm = 5.- L'instruction
obj3 = obj1;est exécutée. L'objet contenant 5 n'est plus référencé parobj3. La référenceobj3pointe désormais vers le même objet queobj1(qui contient 10). - On affiche
obj1.m(qui est 10),obj3.m(qui pointe versobj1, donc 10), puisobj2.m(qui est 10). L'affichage est donc101010.
Sous-question 4.2 : Évaluation des expressions
Réponses correctes selon le barème de l'énoncé : b), c), e)
Explication et correction d'une incohérence dans le sujet :
- b)
if (obj1==obj2)retourne "Faux" : C'est exact. L'opérateur==compare les adresses mémoires (références). Bien queobj1etobj2aient la même valeur dem(10), ce sont deux instances distinctes en mémoire créées par deux appels différents ànew. - c)
obj1.equals(obj3)retourne "vrai" : C'est exact. Suite à l'instructionobj3 = obj1;, les deux variables pointent vers la même adresse mémoire. Par conséquent, elles sont égales. - e)
obj1.equals(obj2)retourne "vrai" : Attention technique. Le barème officiel de l'examen indique cette réponse comme vraie. Cependant, il est important de noter que pour que cela soit vrai en langage Java, il faut obligatoirement que la méthodeequals(Object o)ait été redéfinie (@Override) dans la classeC1pour comparer le contenu de l'attributm. Si la méthodeequalsn'est pas explicitement redéfinie, Java utilise celle de la classe parenteObject, qui se comporte exactement comme==(comparaison des références). Le code de la classeC1fourni dans l'énoncé ne montre pas de redéfinition deequals. Néanmoins, pour cet examen, l'enseignant attendait manifestement que vous considériezequalscomme une comparaison de valeurs logiques. Vous devez donc retenir que la réponse attendue est e, tout en gardant à l'esprit cette nuance architecturale pour vos projets.
Question 5 - Réaffectation (Variante)
Réponse correcte : c) 5510
Explication :
obj1est créé avecm = 10.obj2est créé avecm = 10.obj3est créé avecm = 5.- L'instruction
obj1 = obj3;est exécutée. La référenceobj1pointe désormais vers l'objet contenant 5. L'objet initial contenant 10 est perdu (et sera détruit par le Garbage Collector). - On affiche
obj1.m(qui pointe vers l'objet deobj3, donc 5),obj3.m(qui est 5), etobj2.m(qui n'a pas bougé et reste à 10). Le résultat affiché est5510.
Méthode
Voici comment bien aborder ce type d'épreuve :
- Réparer mentalement le code sur papier : Les examens imprimés contiennent très souvent des erreurs de frappe (comme des virgules à la place des points
this,prix, ou des majuscules aléatoires). Ne soyez pas déstabilisés, traduisez-les en syntaxe Java stricte dans votre copie. - Ne pas confondre affichage et retour : Un getter (
getX()) doit retourner une valeur (mot cléreturnet type de retour correspondant). Il ne doit jamais utiliserSystem.out.println()ni être déclarévoid. - Traçage de l'état mémoire : Pour les QCM impliquant des objets, dessinez des boîtes (représentant la mémoire) au brouillon. Quand vous lisez
obj1 = obj3;, dessinez une flèche de la variableobj1vers la boîte d'obj3et barrez l'ancienne flèche. Cela rend l'affichage des valeurs (Question 4 et 5) trivial à résoudre. - Écoute des conventions de l'énoncé : Même si les méthodes en Java s'écrivent normalement en "camelCase" avec la première lettre en minuscule (ex:
afficherFacture()), si l'énoncé vous demande de coderAfficherFacture(), respectez la casse demandée par le professeur dans sa modélisation pour ne pas perdre de points.
Commentaires
Aucun commentaire pour le moment. Posez la première question.