0% ont trouvé ce document utile (0 vote)
46 vues7 pages

Getters and Setters

Transféré par

fersd2018
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
46 vues7 pages

Getters and Setters

Transféré par

fersd2018
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd

Getters and Setters

Dans les leçons précédentes, tu as appris comment déclarer tes propres


classes à part entière avec des champs et des méthodes. Cela représente
de sérieux progrès, bien joué ! Mais maintenant, je dois t'avouer une triste
vérité. Nous n'avons pas déclaré nos classes correctement ! Comment ça ?
À première vue, il n'y a rien de mal à la classe suivante :
public class Cat {

public String name;


public int age;
public int weight;

public Cat(String name, int age, int weight) {


this.name = name;
this.age = age;
this.weight = weight;
}

public Cat() {
}

public void sayMeow() {


System.out.println("Meow!");
}
}
Et pourtant. Imagine que tu es à ton travail et que tu écris cette classe Cat
pour représenter des chats. Et puis tu rentres chez toi. Pendant ton
absence, un autre programmeur arrive au travail. Il crée sa propre classe
Main, où il commence à utiliser la classe Cat que tu as écrite.
public class Main {

public static void main(String[] args) {

Cat cat = new Cat();


cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
}
Peu importe pourquoi il l'a fait et comment ça s'est produit (peut-être que ce
type a besoin de sommeil). Nous avons un problème plus important : en
l'état, notre classe Cat autorise que des valeurs absolument folles soient
affectées à ses champs. En conséquence, le programme a des objets avec
un état non valide (comme ce chat qui est âgé de -1000 ans). Alors quelle
erreur avons-nous faite lors de la déclaration de notre classe ? Nous avons
exposé les données de notre classe. Les champs name, age et weight sont
public. Ils sont accessibles partout dans le programme : crée simplement
un objet Cat, et tout programmeur aura un accès direct à ses données par
l'intermédiaire de l'opérateur point (.).
Cat cat = new Cat();
cat.name = "";
Ici, nous accédons directement au champ name et définissons sa valeur.
Nous devons nous débrouiller pour protéger nos données de l'ingérence
malvenue d'étrangers. Comment y parvenir ? Tout d'abord, nous devons
marquer toutes les variables d'instance (les champs) avec le modificateur
private. private est le modificateur d'accès le plus strict en Java. Une fois
que tu as fait cela, les champs de la classe Cat ne seront plus accessibles
en dehors de la classe.
public class Cat {

private String name;


private int age;
private int weight;

public Cat(String name, int age, int weight) {


this.name = name;
this.age = age;
this.weight = weight;
}

public Cat() {
}

public void sayMeow() {


System.out.println("Meow!");
}
}

public class Main {

public static void main(String[] args) {

Cat cat = new Cat();


cat.name = "";//error! The Cat class's name
field is private!
}
}
Le compilateur voit cela et génère immédiatement une erreur. Maintenant,
les champs sont plus ou moins protégés. Mais peut-être que nous avons un
peu trop bien restreint l'accès : tu ne peux pas obtenir le poids d'un chat
existant dans le programme, même si tu en as besoin. Cette solution n'est
pas acceptable non plus. En l'état, notre classe est fondamentalement
inutilisable. L'idéal serait de permettre une sorte d'accès limité :

 D'autres programmeurs devraient être en mesure de créer des


objets Cat.
 Ils devraient être en mesure de lire les données à partir d'objets
existants (par exemple, obtenir le nom ou l'âge d'un chat existant).
 Il devrait également être possible d'affecter des valeurs à ces
champs. Mais seules des valeurs valides doivent être autorisées. Nos
objets doivent être protégés contre les valeurs non valides (age = -
1000, et ce genre de loufoqueries)
Ouah, ça nous fait beaucoup d'exigences ! En réalité, tout cela est facile à
réaliser avec les méthodes spéciales appelées getters et setters.

Ces noms proviennent de « get » (« une méthode pour obtenir la valeur


d'un champ ») et « set » (« une méthode pour définir la valeur d'un champ
»). Découvrons de quoi ces méthodes ont l'air dans notre classe Cat :
public class Cat {

private String name;


private int age;
private int weight;

public Cat(String name, int age, int weight) {


this.name = name;
this.age = age;
this.weight = weight;
}

public Cat() {
}

public void sayMeow() {


System.out.println("Meow!");
}

public String getName() {


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

public int getAge() {


return age;
}

public void setAge(int age) {


this.age = age;
}

public int getWeight() {


return weight;
}

public void setWeight(int weight) {


this.weight = weight;
}
}
Comme tu peux le voir, elles se présentent assez simplement :) Leurs
noms se composent souvent de « get »/« set » et du nom du champ
concerné. Par exemple, la méthode getWeight() renvoie la valeur du
champ weight de l'objet sur lequel elle est appelée. Voici à quoi cela
ressemble dans un programme :
public class Main {

public static void main(String[] args) {

Cat smudge = new Cat("Smudge", 5, 4);


String smudgeName = smudge.getName();
int smudgeAge = smudge.getAge();
int smudgeWeight = smudge.getWeight();

System.out.println("Cat's name: " + smudgeName);


System.out.println("Cat's age: " + smudgeAge);
System.out.println("Cat's weight: " +
smudgeWeight);
}
}
Sortie de la console :
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
Maintenant, une autre classe (Main) peut accéder aux champs de la classe
Cat, mais seulement par le biais de getters. Remarque que les getters ont
le modificateur d'accès public, ce qui signifie qu'ils sont disponibles depuis
n'importe où dans le programme. Mais qu'en est-il de l'affectation de
valeurs ? C'est à cela que les méthodes setter servent.
public void setName(String name) {
this.name = name;
}
Comme tu peux le voir, elles sont également simples. Nous appelons une
méthode setName() sur un objetCat, lui passons une chaîne comme
argument, et la chaîne est affectée au champ name de l'objet.
public class Main {

public static void main(String[] args) {

Cat smudge = new Cat("Smudge", 5, 4);

System.out.println("Cat's original name: " +


smudge.getName());
smudge.setName("Mr. Smudge");
System.out.println("Cat's new name: " +
smudge.getName());
}
}
Ici, nous utilisons à la fois des getters et des setters. Tout d'abord, nous
utilisons un getter pour obtenir et afficher le nom d'origine du chat. Ensuite,
nous utilisons un setter pour lui affecter un nouveau nom dans le champ
name (« M. Smudge »). Ensuite, nous utilisons le getter une nouvelle fois
pour obtenir le nom (pour vérifier s'il a vraiment changé). Sortie de la
console :
Cat's original name: Smudge
Cat's new name: Mr. Smudge
Alors quelle est la différence par rapport à ce que nous faisions avant ?
Nous pouvons toujours affecter des valeurs non valides aux champs même
si nous avons des setters :
public class Main {

public static void main(String[] args) {

Cat smudge = new Cat("Smudge", 5, 4);


smudge.setAge(-1000);
System.out.println("Smudge's age: " +
smudge.getAge());
}
}
Sortie de la console :
Smudge's age: -1000 years
La différence est qu'un setter est une méthode à part entière. Et
contrairement à un champ, une méthode te permet d'écrire la logique de
vérification nécessaire pour éviter d'avoir des valeurs inacceptables. Par
exemple, tu peux facilement éviter l'affectation d'un nombre négatif au
champ age :
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
System.out.println("Error! Age can't be
negative!");
}
}
Et maintenant notre code fonctionne correctement !
public class Main {

public static void main(String[] args) {

Cat smudge = new Cat("Smudge", 5, 4);


smudge.setAge(-1000);

System.out.println("Smudge's age: " +


smudge.getAge());
}
}
Sortie de la console :
Error! Age can't be negative!
Smudge's age: 5 years
Dans notre setter, nous avons ajouté une vérification qui nous a protégés
de la tentative de définition de données non valides. L'âge de Smudge n'a
pas été modifié. Tu dois toujours créer des getters et des setters. Même
s'il n'y a aucune restriction sur les valeurs que tes champs peuvent
recevoir, ces méthodes d'assistance ne feront pas de mal. Imagine la
situation suivante : toi et tes collègues écrivez un programme ensemble. Tu
crées une classe Cat avec des champs public : Tous les programmeurs les
utilisent comme ils veulent. Et puis un beau jour, tu réalises : « Zut, tôt ou
tard quelqu'un pourrait accidentellement affecter un nombre négatif au
poids ! Nous devons créer des setters et rendre tous les champs private ! »
Tu fais exactement ça, et tout le code écrit par tes collègues cesse
instantanément de fonctionner. Après tout, ils ont déjà écrit un tas de code
qui accède aux champs de la classe Cat directement.
cat.name = "Behemoth";
Mais maintenant, les champs sont private et le compilateur génère un tas
d'erreurs !
cat.name = "Behemoth";//error! The Cat class's name
field is private!
Dans ce cas, il serait préférable de masquer les champs et de créer des
getters et setters dès le départ. Tous tes collègues les auraient utilisés. Et
si tu as réalisé un peu tard que tu as besoin de restreindre les valeurs d'un
champ d'une manière ou d'une autre, tu aurais simplement pu écrire la
vérification à l'intérieur du setter. Et comme ça tu n'aurais cassé le code de
personne. Bien sûr, si tu veux limiter un champ à un accès en « lecture
seule », tu peux te contenter de créer un getter uniquement. Seules les
méthodes devraient être disponibles à l'extérieur (c'est-à-dire en dehors de
ta classe). Les données doivent être cachées. Nous pourrions comparer
cela à un téléphone mobile. Imagine qu'au lieu d'un téléphone mobile
habituel dans son boîtier, tu as un téléphone avec un boîtier ouvert, avec
toutes sortes de fils et de circuits qui dépassent. Le téléphone fonctionne :
si tu fais un gros effort et que tu tritures les circuits, tu pourrais même
réussir à passer un appel. Mais tu risques surtout de le casser. Au lieu de
cela, le fabricant te donne une interface : l'utilisateur saisit simplement les
bons chiffres, appuie sur le bouton vert d'appel, et l'appel commence. Tu ne
te soucies pas de ce qui se passe à l'intérieur des circuits et des fils, ou de
comment ils font leur travail. Dans cet exemple, le fabricant limite l'accès
aux « entrailles » du téléphone (données) et expose seulement une
interface (méthodes). Ainsi, l'utilisateur obtient ce qu'il veut (la capacité de
passer un appel) sans risque de casser ce qui se trouve à l'intérieur.

Vous aimerez peut-être aussi