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.

Gestion factures achats/ventes – Implémentation Java : constructeurs et méthodes pour Article & LigneFacture

Document source

Afficher l'aperçu du document

Consulter le document original →

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 :

  1. Calculator obj = new Calculator(); instancie l'objet. À ce stade, son attribut d'instance num vaut 100.
  2. obj.calc(2); appelle la méthode calc en passant la valeur 2 au paramètre local num.
  3. Dans la méthode calc, l'instruction this.num = num * 10; est exécutée. Ici, this.num fait référence à l'attribut d'instance de l'objet, tandis que num fait référence au paramètre (qui vaut 2). Donc, l'attribut d'instance devient 2 × 10 = 20.
  4. 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 : C est une classe abstraite. Une classe s'hérite avec extends, on ne peut pas l'implémenter avec implements.
  • b) est vraie : Une classe F peut implémenter une interface B.
  • c) est fausse : L'héritage multiple de classes n'est pas autorisé en Java (une classe ne peut pas utiliser extends sur deux classes A et E simultanément).
  • d) est vraie : Une classe F peut hériter d'une classe E.
  • e) est vraie : L'implémentation multiple d'interfaces est autorisée en Java. Une classe peut implémenter B et D en 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 :

  1. obj1 est créé avec m = 10.
  2. obj2 est créé avec m = 10.
  3. obj3 est créé avec m = 5.
  4. L'instruction obj3 = obj1; est exécutée. L'objet contenant 5 n'est plus référencé par obj3. La référence obj3 pointe désormais vers le même objet que obj1 (qui contient 10).
  5. On affiche obj1.m (qui est 10), obj3.m (qui pointe vers obj1, donc 10), puis obj2.m (qui est 10). L'affichage est donc 101010.

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 que obj1 et obj2 aient la même valeur de m (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'instruction obj3 = 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éthode equals(Object o) ait été redéfinie (@Override) dans la classe C1 pour comparer le contenu de l'attribut m. Si la méthode equals n'est pas explicitement redéfinie, Java utilise celle de la classe parente Object, qui se comporte exactement comme == (comparaison des références). Le code de la classe C1 fourni dans l'énoncé ne montre pas de redéfinition de equals. Néanmoins, pour cet examen, l'enseignant attendait manifestement que vous considériez equals comme 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 :

  1. obj1 est créé avec m = 10.
  2. obj2 est créé avec m = 10.
  3. obj3 est créé avec m = 5.
  4. L'instruction obj1 = obj3; est exécutée. La référence obj1 pointe désormais vers l'objet contenant 5. L'objet initial contenant 10 est perdu (et sera détruit par le Garbage Collector).
  5. On affiche obj1.m (qui pointe vers l'objet de obj3, donc 5), obj3.m (qui est 5), et obj2.m (qui n'a pas bougé et reste à 10). Le résultat affiché est 5510.

Méthode

Voici comment bien aborder ce type d'épreuve :

  1. 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.
  2. Ne pas confondre affichage et retour : Un getter (getX()) doit retourner une valeur (mot clé return et type de retour correspondant). Il ne doit jamais utiliser System.out.println() ni être déclaré void.
  3. 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 variable obj1 vers la boîte d'obj3 et barrez l'ancienne flèche. Cela rend l'affichage des valeurs (Question 4 et 5) trivial à résoudre.
  4. É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 coder AfficherFacture(), respectez la casse demandée par le professeur dans sa modélisation pour ne pas perdre de points.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions