Per quanti si stanno avvicinando per la prima volta alla programmazione Object Oriented, la parola chiave this può essere oggetto di tanti grattacapi. Con questo articolo cercherò di spiegare la sua utilità e la sua importanza, cercando di prenderne in considerazione tutti i vari modi di utilizzo.
La parola “this” in Inglese significa “questo” e non è affatto un caso che i linguaggi Java e C++ (da cui Java stesso ha preso molte ispirazioni) abbiano adottato proprio questa parola per questo tipo di utilizzo. Altri linguaggi utilizzando parole differenti per lo stesso scopo: Delphi utilizza Self, VisualBasic utilizza Me, ecc. Ma cerchiamo di capire che cosa sia questo this; la definizione più ricorrente è “puntatore implicito all’oggetto” e non è certo uno dei più semplici concetti da spiegare.
Partiamo dalle basi: quando si istanzia un oggetto, viene allocata della memoria per poterlo contenere. Questo significa che in memoria viene predisposto tutto lo spazio necessario a contenere tutte le sue proprietà e tutti i suoi metodi. Quando noi utilizziamo un oggetto per programmare (quando, cioè, ne utilizziamo i metodi e le proprietà) lo facciamo sempre attraverso un puntatore (il discorso vale solo per Java). Questo significa che da qualche parte in memoria viene creata una variabile che punta all’oggetto che ci interessa. Vediamo un semplice esempio per schiarirci le idee:
// Creo in memoria la variabile "v"
// che punterà ad un oggetto di tipo Vector
Vector v = new Vector();
// Utilizzo la variabile "v" per riferirmi all'oggetto
v.add( "Ciao" );
Con questo semplice codice viene allocato un oggetto di tipo Vector. Questo oggetto è raggiungibile attraverso il puntatore a cui noi abbiamo dato il nome v. Fin qui nessun problema. Per poter utilizzare le proprietà e i metodi di quel vettore utilizziamo il puntatore v e se dobbiamo passare questo oggetto ad un metodo o al costruttore di una classe, possiamo sempre servirci di v per i nostri scopi. Ma come ci comportiamo se dobbiamo passare ad un metodo o al costruttore di una classe l’oggetto stesso con cui stiamo lavorando? La situazione più comune che ci fa incappare in questa problematica è la costruzione di interfacce grafiche. Supponiamo di dover modellare una finestra che contiene un pulsante. Il pulsante necessita di un ascoltatore e nella maggior parte dei casi, se si ha a che fare con un solo pulsante, non ha senso definire un ascoltatore esterno. Molto più facile ed economico far diventare la finestra stessa un ascoltatore per il pulsante: ci risparmiamo la scrittura di una classe completa, che, per dirla tutta, dovrebbe contenere un solo metodo. Vediamo un esempio:
import javax.swing.*;
import java.awt.event.*;
public class Finestra extends JFrame implements ActionListener {
private JButton pulsante;
public Finestra() {
pulsante = new JButton("Il pulsante");
getContentPane().add( pulsante );
}
public void actionPerformed(ActionEvent ae) {
System.out.println("Ho premuto il pulsante");
}
}
Con questo codice definiamo una finestra con un pulsante. Da notare che ho già definito l’ascoltatore: la classe implementa l’interfaccia ActionListener ed il metodo actionPerformed() è stato debitamente scritto. Ora non ci resta che dire al pulsante che il suo ascoltatore è la finestra stessa. Per fare questo ci arriva in soccorso proprio il puntatore implicito this. E’ sufficiente, infatti, dire al pulsante “guarda che l’ascoltatore per i tuoi eventi è questo oggetto“. Vediamo con il codice come risolvere il problema:
import javax.swing.*;
import java.awt.event.*;
public class Finestra extends JFrame implements ActionListener {
private JButton pulsante;
public Finestra() {
pulsante = new JButton("Il pulsante");
pulsante.addActionListener( this );
getContentPane().add( pulsante );
}
public void actionPerformed(ActionEvent ae) {
System.out.println("Ho premuto il pulsante");
}
}
Quel this in grassetto si riferisce proprio alla finestra che stiamo costruendo. In questo modo, quindi, diciamo al pulsante che la finestra (questo oggetto) è l’ascoltatore per l’evento sollevato da lui quando l’utente ci clicca sopra.
L’importanza del this non si limita solo a questo. L’utilizzo di questa parola riservata può essere facoltativo o obbligatorio a seconda dei casi; dove non si richiede esplicitamente l’utilizzo del this, esso viene sempre utilizzato in modo implicito (senza, quindi, che sia necessario scriverlo). Vediamo, quindi, quali sono i casi in cui l’utilizzo di tale parola diventa obbligatorio:
Il primo punto lo abbiamo già discusso precedentemente: se devo passare l’oggetto ad un metodo o al costruttore di un’altra classe, devo utilizzare il this per riferirmi ad esso.
Uno degli obiettivi più interessanti per cui viene utilizzato il this è poter richiamare un altro costruttore della classe. Una classe può prevedere più costruttori. Questo accade quando si vuole dare la possibilità a chi utilizza la classe di non dover fornire sempre tutte le informazioni in fase di creazione: capita spesso, infatti, che alcune informazioni (quindi alcuni parametri) si possano tralasciare in quanto ci si aspetta che in mancanza di dettagli specifici la classe sopperisca a tale mancanza con dei valori di default. Molti componenti grafici utilizzano questa caratteristica: una JLabel, ad esempio, può essere costruita passando al suo costruttore la stringa da visualizzare oppure non passandogli nulla; nel secondo caso la JLabel richiama automaticamente il costruttore con un parametro, passandogli una stringa vuota. Vediamo come può essere fatto questo, nell’esempio della classe Triangolo vista nell’articolo “Il modificatore static“:
public class Triangolo {
private int base;
private int altezza;
// Costruttore senza parametri
public Triangolo() {
// Costruisco un triangolo di base 3 e altezza 4
this(3, 4);
}
public Triangolo(int b, int h) {
base = b;
altezza = h;
}
}
In questo esempio possiamo vedere come si utilizza il this all’interno di un costruttore per poterne richiamare un altro. E’ importante ricordare che, se si sta richiamando un secondo costruttore, questa chiamata deve essere effettuata prima di ogni altra istruzione.
L’ultimo caso di utilizzo obbligatorio del this che andiamo ad analizzare è quello che permette al programmatore di sopperire alle ambiguità derivanti dalle regole di scope. I dettagli di queste regole esulano dagli scopi di questo articolo e verranno trattate più approfonditamente in futuro. Quello che ci interessa, per il momento, è mettere in luce un aspetto importante: se io definisco una proprietà per una classe (quindi definisco una variabile al di fuori di ogni metodo) essa è visibile a qualunque metodo. Ma cosa accade se ho la necessità di definire una variabile con lo stesso nome, localmente ad un metodo (ad esempio per non aggravare la leggibilità del codice)? O, in particolare, se uno dei parametri di un metodo ha lo stesso nome di una proprietà? In questo caso risulterebbe impossibile, da parte di quel metodo, accedere alla proprietà proprio perchè le regole di scope entrano in gioco nascondendo la variabile esterna. Per risolvere questo problema, il this è la soluzione da adottare. Modifichiamo leggermente il codice d’esempio visto poco fa per la classe Triangolo per far nascere questo problema:
public class Triangolo {
private int base;
private int altezza; public Triangolo() {
this(3, 4);
}
public Triangolo(int base, int altezza) {
// Come assegno i valori di base e altezza?
// La dicitura ‘base = base’ non ha senso
}
}
Come già indicato nell’esempio, se scrivessimo l’istruzione base = base; non otterremmo certo il risultato voluto: assegneremmo alla variabile locale base il suo stesso identico valore. Quello che vogliamo ottenere noi, invece, è che venga assegnato il valore alla proprietà base dichiarata fuori dai metodi e visibile a tutti. Per fare questo si interviene sul codice utilizzando il this:
public class Triangolo {
private int base;
private int altezza;
public Triangolo() {
this(3, 4);
}
public Triangolo(int base, int altezza) {
this.base = base;
this.altezza = altezza;
}
}
In questo modo, tramite l’utilizzo del puntatore implicito, riusciamo perfettamente a riferirci alle proprietà globali dell’oggetto, evitando qualunque ambiguità.
Per dovere di cronaca aggiungo alcune informazioni: quando ci si riferisce a proprietà di oggetti è sempre implicito un this prima del nome della proprietà stessa; questo significa che, se non ci sono motivi di ambiguità sul riferimento di una data variabile, anteporre o tralasciare il this è perfettamente equivalente. Questo perchè le regole di scope non entrano in gioco a coprire la visibilità delle variabili globali. Lo stesso dicasi per i metodi di istanza: richiamare un metodo utilizzando solamente il suo nome e anteponendoci un this (ad esempio, this.calcolaArea() ) sono due modi identici di richiamare lo stesso metodo.
LeleFT
Tags:programmazione object oriented vector visualbasic
4 Risposte
flashmotus
October 12th, 2007 at 22:29
1se questo è un corso via blog (gratuito) di programmazione Object Oriented voglio essere il primo ad essere iscritto e quindi rimango in attesa di nuovi step
p.s. dimenticavo il doveroso grazie
BradipoMissile
October 12th, 2007 at 22:56
2@ flashmotus
Ciao e benvenuto nel mio blog! Allora, per quanto riguarda la sezione “Programmazione Java”, per ora ti posso solo anticipare che sarà portata avanti dal mio amico, nonchè collaboratore, LeleFT (responsabile CED e sistemista per una grossa azienda, nonchè moderatore del Forum di HTML.it).
Il blog è appena partito da una settimana, dammi il tempo di ingranare e vedrai che qui ci sarà di che discutere ed imparare!
P.S. Grazie a te per il commento, il primo in assoluto nel Bradipo Blog! Se vuoi rimanere aggiornato, iscriviti ai miei feed: http://feeds.feedburner.com/BradipoMissile
flashmotus
October 12th, 2007 at 23:52
3iscritto al feed e se ti interessa (?) qui http://www.flashmotus.it/blogger-che-leggono-flashmotus/ puoi segnalarti,
ammazza un pezzo da 90 siede in cattedra, seguo da tempo edit il blog di html ed apprezzo tutta la redazione, un motivo in più per diventare un afecionados del bradipo
BradipoMissile
October 13th, 2007 at 00:01
4@ flashmotus
Ti ho lasciato un commento, ora aspetto che mi aggiungi alla tua lista dei blogger che ti leggono!
Ciao e mi raccomando: resta sempre sintonizzato sul Bradipo Missile…presto altre gustose novità saranno disponibili!
RSS Iscriviti ai Feed dei commenti di questo articolo · TrackBack URI
Lascia un commento... please!!!
Autori
Categories
Calendario
Tag Cloud
Sondaggio
Blog Amici
Gente "Avanti"
Siti Interessanti
Benvenuto!
Qualche statistica
Blog segnalato su
Recent Posts
Recent Comments
Meta