Comment utiliser l'ensemble et obtenir des méthodes, et pourquoi devrais-je les utiliser? Sont-ils vraiment utiles? Et aussi pouvez-vous me donner des exemples de set et obtenir des méthodes?
Les méthodes Set et Get sont un modèle d'encapsulation de données. Au lieu d'accéder directement aux variables de membre de classe, vous définissez les méthodes get
pour accéder à ces variables et les méthodes set
pour les modifier. En les encapsulant de cette manière, vous avez le contrôle sur l'interface publique, si vous devez modifier le fonctionnement interne de la classe à l'avenir.
Par exemple, pour une variable membre:
Integer x;
Vous pourriez avoir des méthodes:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro également mentionné un point important. Si vous souhaitez uniquement autoriser l'accès en lecture au champ pour les classes étrangères, vous pouvez le faire en fournissant uniquement une méthode publique get
et en conservant le set
privé ou en ne fournissant pas un set
à tout.
Je veux ajouter à d'autres réponses que les setters peuvent être utilisés pour éviter de mettre l'objet dans un état invalide.
Par exemple, supposons que je dois définir un identifiant de taxe, modélisé comme une chaîne. La première version du setter peut être la suivante:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
Cependant, nous ferions mieux de ne pas utiliser l'objet pour définir l'objet avec un taxId invalide, afin de pouvoir introduire un contrôle:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
La prochaine étape, pour améliorer la modularité du programme, consiste à rendre le TaxId lui-même en tant qu’objet, capable de se contrôler.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
De même pour le getter, que se passe-t-il si nous n'avons pas encore de valeur? Peut-être que nous voulons avoir un chemin différent, nous pourrions dire:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
Je pense que tu veux quelque chose comme ça:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
Vous appelez simplement une telle méthode sur une instance d'objet. De telles méthodes sont utiles, en particulier si la configuration est supposée avoir des effets secondaires. Par exemple. si vous voulez réagir à certains événements tels que:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Bien sûr, cela peut être dangereux si quelqu'un oublie d'appeler setAge(int)
où il le devrait et règle age
directement à l'aide de this.age
.
Avoir des méthodes d'accès est préférable pour accéder directement aux champs, car il contrôle le mode d'accès aux champs (peut imposer une vérification des données, etc.) et s'adapte aux interfaces (les interfaces ne peuvent pas nécessiter la présence de champs, uniquement des méthodes).
Les setters et les getters sont utilisés pour remplacer directement les variables de membre accédant à des classes externes. si vous utilisez un setter et un getter pour accéder à une propriété, vous pouvez inclure l'initialisation, la vérification des erreurs, les transformations complexes, etc. Quelques exemples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Quelques avantages de l’utilisation de getters et de setters (appelés encapsulation
ou data-hiding
):
(à l'origine répondu ici )
1. Les champs d'une classe peuvent être rendus en lecture seule (en fournissant uniquement le getter) ou en écriture seulement (en fournissant uniquement le sélecteur). Cela donne à la classe un contrôle total sur les personnes qui auront accès à/modifier ses champs.
Exemple:
_class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
_
2. Les utilisateurs d'une classe n'ont pas besoin de savoir comment la classe stocke les données. Cela signifie que les données sont séparées et existent indépendamment des utilisateurs, ce qui permet de modifier et de gérer le code plus facilement. Cela permet aux responsables d'effectuer des modifications fréquentes, telles que des corrections de bugs, des améliorations de la conception et des performances, sans que cela ait d'impact sur les utilisateurs.
De plus, les ressources encapsulées sont uniformément accessibles à chaque utilisateur et ont un comportement identique, indépendant de l'utilisateur, ce comportement étant défini de manière interne dans la classe.
Exemple (obtenir une valeur):
_class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
_
Maintenant, si je voulais retourner deux fois la valeur? Je peux juste modifier mon getter et tout le code qui utilise mon exemple n'a pas besoin de changer et aura deux fois la valeur:
_class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
_
3. Rend le code plus propre, plus lisible et plus facile à comprendre.
Voici un exemple:
Aucune encapsulation:
_class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
_
Avec encapsulation:
_class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
_
Regardez combien de contrôle vous avez sur les informations que vous obtenez et combien cela est plus clair dans le deuxième exemple. Rappelez-vous, cet exemple est trivial et, dans la vie réelle, les cours que vous traiterez avec un grand nombre de ressources auxquelles accèdent de nombreux composants différents. Ainsi, l’encapsulation des ressources permet de savoir plus clairement à quelles ressources nous avons accès et de quelle manière (obtenir ou définir).
Voici good SO thread
sur ce sujet.
Voici good read
sur l’encapsulation des données.
Les réponses ci-dessus résument mieux que je le pouvais le rôle des getters et des setters. Toutefois, je voulais ajouter que votre code devrait idéalement être structuré de manière à réduire l'utilisation de getters et de setters purs, c'est-à-dire ceux sans constructions complexes, validation, etc. comme ils cassent encapsulation. Cela ne signifie pas que vous ne pouvez jamais les utiliser (la réponse de stivlo montre un bon exemple d'utilisation de getters et de setters), essayez simplement de minimiser la fréquence à laquelle vous les utilisez.
Le problème est que les getters et les setters peuvent agir comme solution de contournement pour un accès direct aux données privées. Les données privées sont appelées privées car elles ne sont pas censées être partagées avec d'autres objets. c'est conçu comme une représentation de l'état de l'objet. Autoriser d'autres objets à accéder aux champs privés d'un objet annule l'objectif premier de le rendre privé. De plus, vous introduisez un couplage pour chaque getter ou setter que vous écrivez. Considérez ceci, par exemple:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
Que se passe-t-il si, quelque part sur la route, vous décidez que vous n'avez plus besoin de foo ou que vous voulez en faire un entier? Chaque objet qui utilise la méthode setFoo doit maintenant être modifié avec foo.
simplement parce que la règle OOP: masquage des données et encapsulation. C'est une très mauvaise pratique de déclarer un objet public et de le changer à la volée dans la plupart des situations. Il existe également de nombreuses autres raisons, mais la racine est Encapsulation in OOP. et "acheter un livre ou aller lire sur la programmation orientée objet", vous comprendrez tout ce que vous lisez après avoir lu un livre sur la programmation orientée objet.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
je pense que c'est ce que vous voulez .. et cela s'appelle aussi pojo
Les réponses ci-dessus supposent toutes que l’objet en question est un objet avec un comportement. Une stratégie avancée dans OOP consiste à séparer les objets de données (qui font du Zip, uniquement des champs) et les objets de comportement.
Avec des objets de données, il est parfaitement correct d’omettre les accesseurs et d’avoir des champs publics. Ils n'ont généralement pas de setters, car ils sont le plus souvent immuables - leurs champs sont définis via les constructeurs et jamais plus. Jetez un coup d'œil à Clean Code de Bob Martin ou à Logiciel en croissance OO de Pryce et Freeman ... pour plus de détails.
Les avantages des méthodes get () set () sont les suivants.
Exemple:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Cette réponse est issue d'une autre question.
Votre méthode getAge()
est appelée méthode d'instance en Java.
Pour invoquer une méthode d'instance, vous devez avoir un objet de la classe dans lequel cette méthode est définie.
Par exemple, si cette méthode dans une classe appelée Person
, alors
Créer un objet Personne à l'aide d'un nouvel opérateur
Person p = new Person();
Pour obtenir l’âge d’un objet Person
, utilisez cette méthode.
p.getAge()
c'est le code pour la méthode set
public void setAge(int age){
this.age = age;
}
On dirait que vous essayez de faire quelque chose de similaire à C # si vous voulez une méthode setAge createsetAge(int age){ this.age = age;}
Je ne vois pas de réponse simple à la deuxième question (pourquoi) ici. Alors voilà.
Disons que vous avez un champ public qui est utilisé très souvent dans votre code. Chaque fois que vous décidez que vous devez faire quelque chose de plus avant de donner ou de définir ce champ, vous avez un problème. Vous devez créer un getter et un setter spéciaux pour ce champ et modifier votre code complet de l’utilisation directe du champ à l’utilisation du getter et des setters.
Maintenant, imaginez que vous développiez une bibliothèque largement utilisée par de nombreuses personnes. Lorsque vous devez effectuer un changement comme ci-dessus et définir un accès direct du champ à privé, le code de toutes les personnes utilisant ce champ sera rompu.
L'utilisation de getters et de setters est une question de planification future du code, cela le rend plus flexible. Bien sûr, vous pouvez utiliser des champs publics, en particulier pour les classes simples ne contenant que des données. Mais c'est toujours une bonne idée de créer un champ en privé et de coder une méthode get et set pour celui-ci.