Setter ou constructeurs
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 setter 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 en utilisant le mot-clé" new".
mais quand utilisons-nous des constructeurs et quand utilisons-nous des setters?
10 réponses
vous devez utiliser l'approche du constructeur, lorsque vous voulez créer une nouvelle instance de l'objet, avec les valeurs déjà peuplées(un objet prêt à l'emploi avec une valeur peuplée). De cette façon, vous n'avez pas besoin de vous asseoir explicitement et d'appeler les méthodes de setter pour chaque champ de l'objet pour les remplir.
vous définissez la valeur en utilisant une approche de setter, quand vous voulez changer la valeur d'un champ, après que l'objet a été créé.
pour 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 setter-methods. Je ne dirai pas que tout doit être initialisé dans le constructeur car il existe différentes approches, comme l'évaluation paresseuse qui peut être utilisée même avec des objets immuables .
si vous voulez avoir un constructeur d'utilisation de classe immuable autrement utiliser des setters.
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 voulez créer un nouvel contre-objet, vous utiliseriez un constructeur et définiriez la variable count à l'intérieur de cela. comme ceci:
Counter myCounter = new Counter(1);
si vous voulez changer la variable de comptage pendant l'exécution , vous utiliserez la méthode setter:
myCounter.setCounter(2);
je pense que vous avez posé une bonne question: - mais quand utilisons-nous des constructeurs et quand utilisons-nous des setters?
commençons par quelques concepts. J'espère que cette explication aidera tous ceux qui veulent savoir quand utiliser les méthodes constructors ou setters() et getters () (Accessors et mutateurs). Constructeurs sont similaires à Méthodes , cependant, il ya quelques 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é pour exposer le comportement d'un objet.
2) le constructeur ne doit pas avoir le type de retour. Méthode doit avoir le type de retour.
3) le constructeur est invoqué implicitement. Méthode est invoquée explicitement.
4) Getters () , ou accesseurs, sont des méthodes qui fournissent l'accès aux variables d'instance d'un objet. "1519160920 des" Poseurs() , ou mutateurs, sont des méthodes qui fournissent à l'appelant une occasion de mettre à jour la valeur d'une variable d'instance particulière.
ayant ceci clair, pensons en terme de Programmation Orientée Objet( OOP), pour répondre à l'exigence des principes de OOP (le programmation orientée objets (OOP) est construit sur quatre grands principes : Encapsulation , l'Abstraction de Données , Polymorphisme et Héritage .), Getter() et Setter() méthodes est la clé pour atteindre cet objectif.
voilà une formule qui va vous montrer ce que je veux dire:
domaines privés + publics accessors = = Encapsulation;
comme vous pouvez le voir sur la base de cette formule lorsque nous définissons des champs privés et utilisons des accesseurs publics, nous effectuons encapsulation l'un des 4 principes OOP.
ici je vais vous fournir deux classes, j'ai ajouté des commentaires sur elle pour essayer de faire mon code auto-explication. Prenez ces classes comme un laboratoire sur les méthodes avec Customer
et TestCustomer
[celui avec la méthode main()
] classes, vous pouvez copier le code et l'exécuter vous-même. Remarque, j'ai utilisé deux constructeurs dans le but d'expliquer une classe d'avoir plusieurs constructeurs et ayant publique setters()
et getters()
méthodes afin d'accéder à des variables d'instance privé:
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 test, celle qui a la méthode main()
et qui 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
Nous utilisons l'approche selon le scénario.
-
si nous avons un ensemble de valeurs lors de l'instanciation de l'objet de la classe, alors à ce moment-là, nous utiliserons l'approche du constructeur.
-
lorsque nous ne connaissons pas l'ensemble des valeurs lors de la création de l'instance de l'objet à ce moment-là, nous utiliserons l'approche setter.
dans la plupart des cas je les utilise tous les deux :) (puisque vous 9/10 fois veulent revenir et éditer quelque chose (et ce n'est pas une bonne pratique pour faire une nouvelle instance de celui-ci)
je fais normalement quelque chose comme 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 elle vous pouvez juste utiliser les setters, (une bonne chose si vous par exemple sauvez vos utilisateurs dans un ArrayList, alors vous pouvez juste obtenir l'objet de l'arraylist et juste mettre le champ vous voulez modifier, au lieu de créer un tout nouvel objet :)
Cela dépend du domaine d'application et objet de la classe.
Java beans ont normalement un constructeur no arg et getter/setters pour les variables membres pertinentes. Il y a des avantages à cette approche car les grains de Java sont soutenus hors de la boîte dans de nombreux cadres comme les entretoises et le ressort.
une classe peut également imposer la disponibilité obligatoire des valeurs en ayant de telles variables passées comme paramètres à un constructeur de base. Et non obligatoire les valeurs peuvent être définies par d'autres constructeurs de commodité ou des méthodes de setter.
d'un autre côté, les classes immuables peuvent avoir des constructeurs mais nécessitent des méthodes d'absence qui modifient leur état, y compris les setters.
dans l'ensemble, de telles décisions peuvent être prises en tenant compte de la conception globale de l'application, les cadres 1 il fonctionne dans, le contrat qu'il doit appliquer, etc.
1-bien que, son recommandé cette conception de classe devrait être indépendante des cadres. De bons cadres comme le ressort n'imposent pas de telles exigences.
dans le cas de constructeurs, lorsque vous mettez à jour les champs, vous créez un nouvel objet à chaque fois en utilisant nouveau mot-clé.
Customer customer = new Customer("Tom", 23, 10000);
par exemple, si vous voulez mettre à jour le salaire de Tom, vous devez écrire cette ligne à nouveau avec le salaire mis à jour, ce qui signifie que la mémoire est gaspillée.
dans le cas de méthodes setter vous pouvez définir des champs individuels dans l'objet original seulement.
vous pouvez combiner les deux aproaches. À l'intérieur du constructeur, vous pouvez invoquer les setters des variables instace. 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;
}
}
en termes simples:
Utiliser constructeur si vous pensez que l'initialisation de l'objet est obligatoire avant l'utilisation de l'objet.
Utiliser setter méthode lors de l'initialisation de la variable est non-obligatoire pour utiliser l'objet.
voir la documentation page pour plus de détails.