CodeGym /Cours /JAVA 25 SELF /Surcharge des constructeurs

Surcharge des constructeurs

JAVA 25 SELF
Niveau 14 , Leçon 4
Disponible

1. Syntaxe de la surcharge des constructeurs

Dans la vie, il est rare que tous les objets se créent de la même façon. Imaginez une classe Person (personne). Parfois, nous avons besoin de créer une personne en ne connaissant que son nom. Parfois — son nom et son âge. Et parfois — nous ne savons rien, laissons tout par défaut. Il serait étrange d’obliger l’utilisateur de la classe à fournir systématiquement tous les paramètres, même s’il n’en a pas besoin.

Surcharge des constructeurs — c’est un moyen d’offrir à l’utilisateur de la classe un choix : quels paramètres il souhaite préciser lors de la création de l’objet, et lesquels laisser par défaut. Cela rend la classe flexible et agréable à utiliser.

Analogie :
Dans un bureau d’études, on construit des voitures. Certains commandent une finition de base (sans climatisation, seulement un volant et des roues), d’autres veulent « luxe » (sièges chauffants, Wi‑Fi et que la voiture conduise toute seule). Mais la voiture reste la même classe : simplement des façons différentes de l’assembler !

La surcharge, c’est lorsque plusieurs constructeurs sont déclarés dans une même classe, mais avec des paramètres différents (nombre, type ou ordre). Ils portent tous le même nom que la classe et n’ont pas de type de retour.

Exemple : classe avec des constructeurs surchargés

public class Person {
    String name;
    int age;

    // Constructeur sans paramètres (par défaut)
    public Person() {
        this.name = "Inconnu";
        this.age = 0;
    }

    // Constructeur avec un paramètre
    public Person(String name) {
        this.name = name;
        this.age = 0;
    }

    // Constructeur avec deux paramètres
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Nous pouvons maintenant créer des objets de plusieurs façons :

Person p1 = new Person();                // nom = "Inconnu", âge = 0
Person p2 = new Person("Vasya");         // nom = "Vasya", âge = 0
Person p3 = new Person("Petya", 25);     // nom = "Petya", âge = 25

Comment Java sait-il quel constructeur utiliser ?

Java regarde le nombre et les types des arguments que vous passez après new. Si vous écrivez new Person("Vasya"), le compilateur cherche un constructeur avec un paramètre de type String. Si vous écrivez new Person("Petya", 25), il faut un constructeur avec les paramètres String et int.

2. Appeler un constructeur depuis un autre : this(...)

Parfois, lors d’une surcharge de constructeurs, une partie du code se répète. Par exemple, vous voulez que tous les constructeurs définissent obligatoirement le nom, et que l’âge, s’il n’est pas fourni, vaille zéro. Pour ne pas dupliquer la même logique dans chaque constructeur, on peut appeler un constructeur depuis un autre au moyen du mot-clé this(...).

Exemple

public class Person {
    String name;
    int age;

    // Constructeur avec deux paramètres
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Le constructeur avec un paramètre appelle un autre constructeur
    public Person(String name) {
        this(name, 0); // appelle Person(String name, int age)
    }

    // Le constructeur sans paramètres appelle un autre constructeur
    public Person() {
        this("Inconnu", 0);
    }
}
public Person(String name) {
    this(name, 0); // appelle Person(String, int)
}
Appel d’un constructeur depuis un autre via this(...)

Règle importante : L’appel d’un autre constructeur via this(...) doit être la première ligne du constructeur !

Pourquoi faire cela ?

  • Réduit la duplication de code.
  • Si vous décidez de modifier la logique d’initialisation (par exemple, changer la valeur par défaut), vous n’aurez à le faire qu’à un seul endroit.
  • Le code devient plus clair et plus facile à maintenir.

3. Exemples pratiques : surcharge dans une classe réelle

Supposons que nous ayons une classe Account — un compte bancaire. Parfois nous ne connaissons que le nom du propriétaire, parfois nous voulons indiquer tout de suite le solde initial, et parfois aussi la devise.

Exemple de classe avec des constructeurs surchargés

public class Account {
    String owner;
    double balance;
    String currency;

    // Constructeur avec trois paramètres
    public Account(String owner, double balance, String currency) {
        this.owner = owner;
        this.balance = balance;
        this.currency = currency;
    }

    // Constructeur avec deux paramètres (devise par défaut — "EUR")
    public Account(String owner, double balance) {
        this(owner, balance, "EUR");
    }

    // Constructeur avec un paramètre (solde = 0, devise = "EUR")
    public Account(String owner) {
        this(owner, 0.0, "EUR");
    }

    // Constructeur sans paramètres (propriétaire — "Inconnu", solde = 0, devise = "EUR")
    public Account() {
        this("Inconnu", 0.0, "EUR");
    }

    public void printInfo() {
        System.out.println(owner + ": " + balance + " " + currency);
    }
}

Utilisation

public class Main {
    public static void main(String[] args) {
        Account acc1 = new Account("Ivan", 1000, "USD");
        Account acc2 = new Account("Mariya", 500);
        Account acc3 = new Account("Pyotr");
        Account acc4 = new Account();

        acc1.printInfo(); // Ivan: 1000.0 USD
        acc2.printInfo(); // Mariya: 500.0 EUR
        acc3.printInfo(); // Pyotr: 0.0 EUR
        acc4.printInfo(); // Inconnu: 0.0 EUR
    }
}

Pourquoi est-ce pratique ?

  • On peut créer des objets avec des niveaux de détail différents.
  • Il n’est pas nécessaire d’indiquer tous les paramètres à chaque fois (surtout s’ils sont souvent identiques).
  • La classe est facile à étendre : si un nouveau paramètre apparaît, on peut ajouter un constructeur supplémentaire.

4. Erreurs courantes lors de la surcharge de constructeurs

Erreur n° 1 : confusion entre types et ordre des paramètres.
Si vous avez deux constructeurs — Person(String name, int age) et Person(int age, String name) — le compilateur les distinguera, mais pour l’utilisateur de la classe cela peut être très déroutant. Mieux vaut éviter ce genre de situations.

Erreur n° 2 : absence de constructeur par défaut.
Si vous n’avez déclaré que des constructeurs avec paramètres et que vous essayez ensuite de créer un objet sans paramètres — vous obtiendrez une erreur de compilation. Ajoutez toujours un constructeur sans paramètres si vous en avez besoin.

Erreur n° 3 : tentative d’appeler un autre constructeur ailleurs que sur la première ligne.
L’appel this(...) doit toujours être la première ligne du constructeur. Si vous écrivez quoi que ce soit avant — vous obtiendrez une erreur de compilation.

Erreur n° 4 : bouclage des appels de constructeurs.
Si un constructeur s’appelle lui-même (directement ou via une chaîne), cela entraînera une erreur de compilation à cause d’une récursion infinie.

Erreur n° 5 : champs non initialisés.
Si vous oubliez d’initialiser un champ dans le constructeur (ou dans la chaîne d’appels), l’objet peut se retrouver dans un état incorrect. Vérifiez que tous les champs ont des valeurs cohérentes après la création de l’objet.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION