web-dev-qa-db-fra.com

Méthodes ou constructeurs Setter

jusqu'à présent, j'ai vu deux approches pour définir la valeur d'une variable en Java. Parfois, un constructeur avec des arguments est utilisé, d'autres méthodes de définition sont utilisées pour définir la valeur de chaque variable.

Je sais qu'un constructeur initialise une variable d'instance à l'intérieur d'une classe une fois qu'une classe est instanciée à l'aide du "nouveau" mot-clé.

Mais quand utilisons-nous des constructeurs et quand utilisons-nous des setters?

37
ssayyed

Vous devez utiliser l'approche constructeur, lorsque vous souhaitez créer une nouvelle instance de l'objet, avec les valeurs déjà remplies (un objet prêt à l'emploi avec une valeur remplie). De cette façon, vous n'avez pas besoin d'appeler explicitement les méthodes de définition pour chaque champ de l'objet pour les remplir.

Vous définissez la valeur à l'aide d'une approche de définition, lorsque vous souhaitez modifier la valeur d'un champ, une fois l'objet créé.

Par exemple: -

MyObject obj1 = new MyObject("setSomeStringInMyObject"); // Constructor approach
// Yippy, I can just use my obj1, as the values are already populated
// But even after this I can change the value
obj1.setSomeString("IWantANewValue"); // Value changed using setter, if required.
..
MyObject obj2 = new MyObject();
obj2.setSomeString("setSomeStringNow"); // Setter approach
// values weren't populated - I had to do that. Sad :(

Et comme Axel l'a mentionné, si vous voulez créer des objets immuables, vous ne pouvez pas utiliser l'approche des méthodes de définition. Je ne dirai pas que tout doit être initialisé dans le constructeur car différentes approches existent, comme l'évaluation paresseuse qui peut être utilisée même avec des objets immuables .

42
SudoRahul

Je pense que vous avez posé une bonne question: - Mais quand utilisons-nous des constructeurs et quand utilisons-nous des setters?

Commençons d'abord par quelques concepts. J'espère que cette explication aide tous ceux qui veulent savoir quand utiliser les méthodes constructeurs ou setters () et getters () (accesseurs et mutateurs). Constructeurs sont similaires à Méthodes, cependant il y a peu de différences entre constructeur et ( méthode en Java:

1) ( Le constructeur est utilisé pour initialiser l'état d'un objet. Méthode est utilisée pour exposer le comportement d'un objet.

2) ( Le constructeur ne doit pas avoir de type de retour. Méthode doit avoir un type de retour.

3) ( Le constructeur est invoqué implicitement. La méthode est invoquée explicitement.

4) Getters () , ou accesseurs, sont des méthodes qui permettent d'accéder aux variables d'instance d'un objet. Setters () , ou mutateurs, sont des méthodes qui permettent à l'appelant de mettre à jour la valeur d'une variable d'instance particulière .

Cela étant clair, réfléchissons en termes de programmation orientée objet (POO), pour répondre à l'exigence de OOP principes (la programmation orientée objet (POO) est construit sur quatre grands principes : Encapsulation , Abstraction des données , Polymorphisme et Héritage .), Les méthodes Getter () et Setter () sont la clé pour y parvenir.

Voici une formule qui va vous montrer ce que je veux dire:

Champs privés + accesseurs publics == Encapsulation;

Comme vous pouvez le voir sur la base de cette formule lorsque nous définissons des champs privés et utilisons des accessoires publics, nous effectuons l'encapsulation de l'un des 4 OOP principaux).

Ici, je vais vous fournir deux classes, j'ai ajouté un commentaire pour essayer de rendre mon code explicite. Prenez ces classes comme un laboratoire sur les méthodes avec Customer et TestCustomer [celle avec les classes main() method], vous pouvez copier le code et l'exécuter vous-même. Remarque J'ai utilisé deux constructeurs pour expliquer une classe ayant plusieurs constructeurs et ayant des méthodes publiques setters() et getters() afin d'accéder aux variables d'instance privées:

package com.exercise.lecture2;

/**
 * 1) Create a Customer class that has the following attributes:
 * name, SSN.
 * 2) This class should have two methods: getName() and getSSN().
 * 3) If the class is instantiated with only a SSN, then give the default name of "John Doe". (HINT: Use two constructors)
 * 4) Also, add a method toString(), that returns a string representation of the customer object (name and SSN concatenated).
 *      Make sure to set this method public.
 * 5) Create a class to test your program (e.g. a class that include the main() method). In your test program, instantiate
 *      three customers and print out the value using toString() method.
 * 
 * @author Samuel M.
 *
 */

//this class is complemented with class  TestLabCustomer.Java
public class LabCustomer {

// Private filds: name and socialSecurityNum
    private String name;
    private int socialSecurityNum;

    // constructors
    public LabCustomer(String name, int socialSecurityNum) {
        this.name = name;
        this.socialSecurityNum = socialSecurityNum;
    }

    /** The keyword 'this' can be used to call a constructor from a constructor,
     * when writing several constructor for a class, there are times when
     * you'd like to call one constructor from another to avoid duplicate code.
     */
    // Account with This() on a second constructor
    public LabCustomer(int socialSecurityNum) {
        this("John Doe", socialSecurityNum); // default name is printed if only the SSN is provided
    }

    // Public accessors (getters and setters)
    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    int getSSN() {
        return socialSecurityNum;
    }

    void setSSN(int socialSecurityNum) {
        this.socialSecurityNum = socialSecurityNum;
    }


    // instance method
    public String toString() { //overriding the toString() method 
        return ("Customer name: " + getName() + ", SSN#: " + getSSN() ); // concatenating the name and SSN

    }
}

Voici la classe de test, celle qui a la méthode main() et appelle une méthode d'instance après instanciation d'un objet de la classe previews:

package com.exercise.lecture2;

//this class is complemented with class  LabCustomer.Java
public class TestLabCustomer {

    public static void main(String[] args) {
        // Instantiating an object of class LabCustomer and creating three customers objects
        LabCustomer cust1 = new LabCustomer("Juan Melendez", 123457789);
        LabCustomer cust2 = new LabCustomer("Mary Lee", 125997536);
        LabCustomer cust3 = new LabCustomer(124963574); // when instantiating with no "name", the default (John Doe) is printed 

        /**
         * Once you've instantiated an object and have an object variable,
         * you can use object variable to call an instance method. 
         *  e.g.:
         *  object variables: cust1, cust2, cust3
         *  call the method toString() using the object variable and dot [.] in order to perform the method call.
         */
        // calling method toString() in class LabCustomer to print customer values
        System.out.println(cust1.toString());
        System.out.println(cust2.toString());
        System.out.println(cust3.toString());

    }

}

résultat:

Nom du client: Juan Melendez, SSN #: 123457789

Nom du client: Mary Lee, SSN #: 125997536

Nom du client: John Doe, SSN #: 124963574

8
S. Mayol

Si vous voulez avoir une classe immuable, utilisez un constructeur sinon utilisez des setters.

4
Evgeniy Dorofeev

En termes simples:

Utilisez le constructeur si vous pensez que l'initialisation est obligatoire avant de pouvoir utiliser l'objet.

Utilisez la méthode setter lorsque l'initialisation de la variable n'est pas obligatoire pour utiliser l'objet.

Reportez-vous à la documentation page pour plus de détails.

3
Ravindra babu

Disons que nous avons une classe, nommée Counter:

public class Counter{
    int count;
    //constructor
    public Counter(int c){
        count = c;
    }
    public void setCounter(int newCounter){
        count = newCounter;
    }
}

Dans la classe ci-dessus, lorsque vous souhaitez créer un nouvea objet Counter, vous utiliseriez un constructeur et définiriez la variable count à l'intérieur. ainsi:

Counter myCounter = new Counter(1);

Si vous souhaitez modifier la variable de comptage pendant l'exécution, vous utiliseriez la méthode setter:

myCounter.setCounter(2);
2
hmir

Nous utilisons l'approche en fonction du scénario.

  1. Si nous avons un ensemble de valeurs lors de l'instanciation de l'objet de la classe, nous utiliserons alors l'approche constructeur.

  2. Lorsque nous ne connaissons pas l'ensemble de valeurs lors de la création d'une instance de l'objet à ce moment, nous utiliserons l'approche setter.

1
eatSleepCode

Cela dépend du domaine d'application et du but de la classe qu'il contient.

Les beans Java ont normalement un constructeur sans arg et des getter/setters pour les variables membres pertinentes. Cette approche présente des avantages car Java sont pris en charge dès la sortie de la boîte dans de nombreux frameworks comme Struts et Spring.

Une classe peut également appliquer la disponibilité obligatoire des valeurs en faisant passer ces variables en tant que paramètres à un constructeur de base. Et les valeurs non obligatoires peuvent être définies via d'autres constructeurs de commodité ou méthodes de définition.

D'un autre côté, les classes immuables peuvent avoir des constructeurs mais nécessitent des méthodes d'absence qui modifient son état, y compris des setters.

Dans l'ensemble, ces décisions peuvent être prises en tenant compte de la conception globale de l'application, des cadres1 il entre en jeu, il doit contracter, etc.

1 - Bien qu'il soit recommandé que la conception des classes soit indépendante des frameworks. De bons frameworks comme Spring n'appliquent pas de telles exigences.

1
sgp15

Dans le cas des constructeurs, lorsque vous mettez à jour des champs, vous créez un nouvel objet à chaque fois en utilisant le mot-clé new.

Customer customer = new Customer("Tom", 23, 10000);

Par exemple, si vous souhaitez mettre à jour le salaire de Tom, vous devez réécrire cette ligne avec le salaire mis à jour, cela signifie que la mémoire est gaspillée.

Dans le cas des méthodes de définition, vous pouvez définir des champs individuels dans l'objet d'origine uniquement.

1
Sushil kumawat

Dans la plupart des cas, j'utilise les deux :) (puisque vous 9/10 fois voulez revenir et éditer quelque chose (et ce n'est pas une bonne pratique pour en faire une nouvelle instance)

Je fais normalement quelque chose comme des tihs

public class User {

    private int id;
    private String initials;
    private String firstName;
    private String lastName;
    private String email;

    public User() {
        this(0, "", "", "");
    }

    public User(int id, String firstName, String lastName, String email) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
   // Getters and setters should be here
}

Et quand vous voulez éditer quelque chose avec, vous pouvez simplement utiliser les setters, (une bonne chose si vous enregistrez par exemple vos utilisateurs dans une ArrayList, alors vous pouvez simplement obtenir l'objet de l'arraylist et simplement définir le champ que vous voulez éditer , au lieu d'en faire un tout nouvel objet :)

1
Kasper Franz

Vous pouvez combiner les deux approches. A l'intérieur du constructeur, vous pouvez appeler les setters de variables d'instance. Quelque chose comme:

public class TestClass {
    private String someField;

    public TestClass(String someField) {
        setSomeField(someField);
    }

    public String getSomeField() {
        return someField;
    }

    public void setSomeField(String someField) {
        this.someField = someField;
    } 
}
0
Cold