Java this. [Résolu/Fermé]

Signaler
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
-
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
-
Bonjour,


J'ai du mal a comprendre le this. en java.

D'apres ce que j'ai compris il a le meme rôle que les getters (get.) et setters (set.) .
Sauf qu'on utilise le this pour les variable private se trouvant dans la meme classe.
On utilise le get. et set. pour les variables se trouvant dans d'autres classes.

Es ce bien ca?

8 réponses

Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Pas du tout ! Ou alors de très très loin...

Lorsque tu créés un objet, tu fais appel à son constructeur, et tu en récupères un référence
Object obj = new Object(); // obj est une référence à l'objet créé.

Une méthode s'applique à un objet en particulier, par exemple : obj.toString()

Le problème c'est que lorsque tu crées ta propre classe, tu vas définir des méthodes sans connaître d'avance la référence qui sera utilisée. C'est à ça que sers le mot-clé this, c'est une référence sur l'objet utilisé.

Exemple :

public class Tata  
{  
    private int n = 3;  

    public int toto()  
    {  
        return this.n;  
    }  

    public static void main(String...args)  
    {  
        Tata titi = new Tata();  
        int a = titi.toto(); // le "this" dans la méthode toto() correspond à la référence "titi", c'est donc équivalent (dans ce cas) à faire "titi.n"  
    }  
}

Remarque : dans de nombreux cas, le this est implicite, c'est à dire qu'on peux l'omettre, sans risque de confusion. Ici j'aurais pu faire directement return n;

Voici un exemple (presque) concret où this est utile :

public class Reel 
{ 
    private double x; 

    public Reel(double val) 
    { 
        x = val; 
    } 

    public Reel multiplier(Reel r) 
    { 
        return new Reel(this.x * r.x); // on multiplie la valeur courante par celle de r 
        // ou avec le this implicite : return new Reel(x * r.x); 
    } 

    public Reel carre() 
    { 
        return this.multiplier(this); // on se multiplie soi même 
        // ou avec le this implicite : return multiplier(this); 
        // ici le mot-clé this est nécessaire pour la méthode "multiplier" 
    } 
}
La confiance n'exclut pas le contrôle
2
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Salut,

Pour faire très court... le this fait référence à l'objet (instance de la classe) courant manipulé dans la classe.
Dès que tu manipules un objet (à travers les méthodes définies dans sa classe) cet objet est représenté par this.
Pour les accesseurs, sur le fond le résultat est le même. La différence tient dans le fait que tu peux intégrer des règles de gestion dans tes accesseurs et forcer leur utilisation en mettant tes attributs en private (ou protected).
Par exemple imaginons que tu gères un panier sur une boutique en ligne et que dans ta classe Panier tu ais une variable quantité (même si en réalité ce ne serait pas très propre... mais c'est plus simple pour expliquer) que tu incrémentes ou décrémentes en fonction des produits ajoutés/retirés.
Cette variable quantité ne doit en aucun cas se retrouver négative, ça n'aurait pas de sens et ça nuirait à l'intégrité du panier. En forçant l'utilisation d'un Setter du type :

public void setQuantité(int quantite){
if(q<0){
throw new MachinException(); //ou message d'erreur
}
else{
this.quantite = quantite; //le this fait bien référence à l'objet courant
}
}

Tu as en quelques sortes la garantie de ne pas avoir de quantité négative. Tes objets Panier seront donc intègres de ce point de vue quelles que soient les manipulations que tu tentes de faire de l'extérieur (c'est à dire dans tes classes qui utiliseront la classe Panier) car tu auras définis des contraintes fonctionnelles liées à la définition d'un Panier (un panier peut par définition être vide mais ne peut pas contenir de contenu négatif...)

Bref, j'ai fait long.
2
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
merci
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
en résumé , si j'ai bien compris: le mot clé this sert a référencer un objet qui n'a pas encore été instancié?
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Non, parce que this sera toujours instancié, puisque s'il ne l'était pas la méthode ne serait pas appelé !
En résumé, this, c'est l'objet avec lequel on appelle la méthode.
Si je fait t.toto(), à l'intérieur de toto on aura this==t, de même si je fais t2.toto(), on aura this==t2.
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
les accesseurs => méthodes servant à accéder aux données de nos objets
et les méthodes de classe => méthodes servant à la gestion de nos objets.

Les méthodes de classe vont vous permettre de gérer, éditer, afficher... faire tout ce que vous voudrez avec vos objets.

les methodes de classe (this.) sert a gerer , editer, afficher des objets.
les accesseurs (set.) sert a editer un objet , (get.) sert a afficher un objet (obtenir sa valeur).

je vois aucune différence. Je cherche mais je n'arrive vraiment pas a comprendre quand on dois utiliser les accesseurs et quand on doit utiliser les méthodes de classe.

j'ai du mal avec la POO
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Formellement, un accesseur est une méthode, il n'y a donc pas vraiment de différence pour Java, c'est ce que l'on en fait et le sens que l'on donne à la méthode qui va faire la différence.
Par exemple, un getteur ou un setteur, ne commence pas nécessairement par le nom get ou set (même si c'est recommandé), on reconnaît un getteur au fait qu'il permette d'accéder à une valeur d'état, mais ce n'est pas forcément un champ de l'objet, on peut le calculer dans la méthode.

Par exemple une date est généralement représentée Unix-like par une valeur long qui valait 0 le 1er janvier 1970 à minuit, et qui est incrémenté toutes les secondes.
On peut avoir des getYear, getHour, setMonth, setSeconds... qui accèdent à des valeurs représentatives de la date, mais qui en fait les calcules à partir de la seule valeur que l'on ait : le long.
Une méthode qui ne serait pas un get/set serait par exemple faire la différence entre deux dates, en l'occurrence entre la valeur courante (this) et une autre date.

Le mot clé this (qui est formellement défini dans le langage pour désigner un objet) n'a pas grand chose à voir avec les méthodes get/set (qui ne sont que des conventions pour nommer des méthodes)
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
merci, je pense avoir compris.

En conclusion, si j'ai bien compris:

Le This sert tout simplement a référencer l'objet de la classe courante. Si on veux appeler une variable de la classe courante on dois faire this.maVar .

le accesseurs on les nomme get et set par convention mais ce sont juste des convention pour nommer des méthodes nous permettant d'acceder a des variables private.
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Remarque : pour this.maVar on peut généralement écrire maVar où this est implicite, le seul cas où il faut explicitement mettre c'est lorsqu'il y a une variable locale ou un paramètre qui s'appelle aussi maVar

Exemple :

void setMaVar(int val)
{
    maVar = val; // this implicite
}

void setMaVar(int maVar)
{
    this.maVar = maVar; // this explicite pour ne pas confondre
}
Pour le this c'est comme tu dis, même on est pas "obligé" de le spécifier. On "doit" le spécifier quand on veut manipuler un attribut de l'objet qui a le même nom qu'un paramètre (voir l'exemple avec le setter) ou lorsqu'on souhaite passer l'objet courant en paramètre d'une méthode appelé (le this.multiplier(this) de KX).
Pour les accesseurs ce sont des conventions qui garantissent l'intégrité des objets en fonction de contraintes définies. Une fois que tes classes sont blindées et garantissent des objets cohérents elles sont plus facilement maintenables, réutilisables dans d'autres projets, extensibles, dérivables... bref c'est l'idée de la POO.
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
oui mais pour etre propre vaut mieux le mettre meme si il est implicite, ca facilite la compréhension?

Enfin je suppose que mes prof préfereraient que je le mette!
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
bon je crois que je peu passer aux array
Oui pour tes profs ça montre que t'a compris... après en entreprise (en fonction de l'entreprise) ça peut faire un peu scolaire... Personnellement je les mets dans les constructeurs et dans les setteurs systématiquement (car mes paramètres ont le même nom). Dans les getters et les méthodes, pas systématiquement... c'est toi qui voit ce que tu préfères.
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
Un grand merci a vous !!
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
je viens de faire un petit programme qui fonctionne parfaitement avec des this. J'espere ne pas avoir fait d'erreur:

package appartements;


public class Main {


public static void main(String[] args) {
//creation des adresse
Adresse adr1 = new Adresse("Fescou",154,4750,"rochefort");
Adresse adr2 = new Adresse("beauraing",14,7514,"Namur");
Adresse adr3 = new Adresse("Fetinne",175,4751,"Liege");

Appartement app1 = new Appartement(50,3,1,2013,adr1.affichageAdresse());
Appartement app2 = new Appartement(60,5,2,2012,adr2.affichageAdresse());
Appartement app3 = new Appartement(20,1,3,2016,adr1.affichageAdresse());

app1.affichageAppartement();
app2.affichageAppartement();
app3.affichageAppartement();
}
}




public class Adresse {
private String nom = new String();
private int numero;
private int codePostal;
private String localite = new String();

public int getCodePostal() {
return codePostal;
}

public String getLocalite() {
return localite;
}

public String getNom() {
return nom;
}

public int getNumero() {
return numero;
}

public void setCodePostal(int codePostal) {
this.codePostal = codePostal;
}

public void setLocalite(String localite) {
this.localite = localite;
}

public void setNom(String nom) {
this.nom = nom;
}

public void setNumero(int numero) {
this.numero = numero;
}

public Adresse(String nom,int numero,int codePostal,String localite){
this.nom = nom;
this.numero = numero;
this.codePostal = codePostal;
this.localite = localite;
}
public String affichageAdresse(){

return "Adresse: rue de "+this.localite+" "+this.codePostal+","+this.numero+" "+this.nom;
}
}





public class Appartement {

private int surface; // en m²
private int nbrChambre;
private int matricule;
private int anneeFinBail;
private String adresse;



//return le loyer mensuel sur base du nbr de chambre et de la surface
public int calculLoyerMensuel(){
int loyerMensuel=0;
loyerMensuel = 100 * this.nbrChambre + 5 * this.surface;
return loyerMensuel;
}

public int getAnneeFinBail() {
return anneeFinBail;
}

public int getMatricule() {
return matricule;
}

public int getNbrChambre() {
return nbrChambre;
}

public int getSurface() {
return surface;
}

public void setAnneeFinBail(int anneeFinBail) {
this.anneeFinBail = anneeFinBail;
}

public void setMatricule(int matricule) {
this.matricule = matricule;
}

public void setNbrChambre(int nbrChambre) {
this.nbrChambre = nbrChambre;
}

public void setSurface(int surface) {
this.surface = surface;
}

public Appartement(int surface,int nbrChambre,int matricule,int anneeFinBail,String adresse){
this.surface = surface;
this.nbrChambre = nbrChambre;
this.matricule = matricule;
this.anneeFinBail = anneeFinBail;
this.adresse = adresse;
}

//renvoie true si l'appartement est dispo
public boolean disponibilite(){
boolean disponibilite = false;

//demande a l'utilisateur en quel annee nous sommes
Scanner sc = new Scanner(System.in);
System.out.print("Quel annee sommes nous?");
int year = sc.nextInt();

//verifie si l'appartement est dispo
if(this.anneeFinBail < year){
disponibilite = true;
}

return disponibilite;
}

//affichage des données de l'appart
public void affichageAppartement(){
boolean dispo = disponibilite();
int loyerMensuel = calculLoyerMensuel();
System.out.printf("Appartement numero %d\n",matricule);
System.out.printf("surface: %d\n",surface);
System.out.printf("Nombre de chambres: %d\n",nbrChambre);
System.out.printf("Adresse: %s\n",adresse);
System.out.printf("Le loyer mensuel est de: %d\n",loyerMensuel);
if(dispo == true){
System.out.println("L'appartement est disponible\n");
}
else{
System.out.println("L'appartement n'est pas disponible\n");
}

}

}
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Si tu voulais mettre TOUT les this, alors il t'en manque !
Dans les get par exemple, tu utilises implicitement this :

public int getAnneeFinBail()
{
    return this.anneeFinBail;
}


De même pour les méthodes, c'est this qui les appelles :

public void affichageAppartement()
{
    boolean dispo = this.disponibilite();


Mais bon, je ne vais pas tous les faire parce que je trouve personnellement que le code est plus lisible lorsqu'il est le moins long possible et que le this alourdit inutilement les instructions.
Mais on pourrait faire pire, puisque le this est un membre de la classe :

public int getAnneeFinBail()
{
    return Appartement.this.anneeFinBail;
}

Là autant te dire que si tu en mets deux ou trois à la suite, on ne comprends plus rien au code !
J'ai pas tout vérifié mais ça me semble pas mal.
Si tu veux pousser un peu plus loin dans les concepts objets, voici quelques trucs.
Tes méthodes affichageAdresse() et affichageAppartement() devraient s'appeler toString() et retourner un String décrivant l'objet. C'est ce que tu as fait pour affichageAdresse() mais pas pour affichageAppartement(). En théorie les classes de type métier (comme c'est le cas pour Appartement et Adresse) ne doivent pas gérer l'affichage mais juste implémenter une méthode toString() retournant une chaine de caractères.
Pour bien partir sur une classe métier en POO il faut penser à avoir :
Un constructeur par défaut
Un constructeur avec tous les paramètres
Des getters/setters pour toutes tes variables privées ou protégées
Un toString()

Sur cette base tu peux en théorie tout faire et construire n'importe quel objet (en mettant les paramètres des attributs que tu ne souhaite pas instancier à NULL ou 0 dans le constructeur paramétré). A toi de voir si ensuite tu veux plus de souplesse et ajouter/supprimer/modifier certains trucs. Bref tu t'adaptes, mais c'est une bonne base assez universelle.
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
merci des conseils.
Pour les getters et setters netbeans les génère automatiquement sans le this, et comme tu me l'as dit, les mettre risquerais d'alourdir le code.

si je renomme affichageAdresse() et affichageAppartement() en toString(), après je vois pas trop comment les différencier quand je les appelle. A moin que tu veuille dire: adresseToString() et affichageToString.

En fait j'aurais du :
-soit mettre l'affichageAppartement dans un String comme j'ai fait avec l'affichage adresse
-ou creer une classe dialogueUtilisateur qui aurait eut pour but de gerer l'affichage
Messages postés
78
Date d'inscription
jeudi 22 décembre 2011
Statut
Membre
Dernière intervention
24 janvier 2013
3
ah ok, je viens de voir pour la methode toString, je vais me pencher las dessus.

en tout cas merci pour tout