- Learn
- Guida Delphi
- Classi ed Oggetti: i metodi
Classi ed Oggetti: i metodi
- di Carlo Marona
Metodi
Abbiamo visto in precedenza cosa è e come viene definito un metodo. Ora vediamo di approfondire l’argomento. In Object Pascal ci sono due parole chiave che rientrano nella creazione ed utilizzo dei metodi; queste sono Inherited e Self.
Inherited permette di richiamare i metodi dell’antenato da cui deriva la classe a cui appartiene il nuovo metodo. Per meglio dire, se la classe da cui abbiamo ereditato definisce un metodo MioMetodo scrivendo il codice seguente richiamo quel metodo
Procedure MiaClasse.MioMetodo(Valore : Integer);
Begin
Inherited;
End;
Ciò permette di aggiungere funzionalità al metodo di base ereditato.
Non specificando nessun identificatore dopo la parola riservata Inherited, questa farà riferimento al metodo dell’antenato avente lo stesso nome del metodo in cui si trova la parola chiave Inherited. Se dopo di essa non viene specificato alcun parametro, verranno passati al metodo ereditato gli stessi parametri passati al metodo della classe che si sta definendo.
Se invece la parola Inherited è seguita da un identificatore di metodo, questa effettuerà una chiamata al metodo corrispondente all’identificatore indicato ricercandolo a partire dall’antenato immediato.
La parola chiave Self permette di fare riferimento, all’interno dell’implementazione di un metodo, all’oggetto dal quale il metodo viene chiamato.
Collegamento dei metodi
I metodi possono essere di tre tipi: statici, virtuali, dinamici. Quando un metodo viene definito, per impostazione predefinita è statico.
Nella chiamata di un metodo statico, l’implementazione da attivare viene determinata in base al tipo, dichiarato in fase di compilazione, della classe che viene utilizzata per la chiamata del metodo.
Quindi per esempio, avendo le dichiarazioni di classi seguenti
Type TClasse1 = Class
Procedure Metodo1;
End;
TClasse2 = Class(TClasse1)
Procedure Metodo1;
End;
ed eseguendo il seguente codice
Var Classe1 : TClasse1;
Classe2 : TClasse2;
Begin
Classe1 := TClasse1.Create;
Classe1.Metodo1;
//L’implementazione utilizzata è quelle di TClasse1
Classe1.Destroy;
Classe1 := TClasse2.Create;
Classe1.Metodo1;
//L’implementazione utilizzata è quelle di TClasse1
TClasse2(Classe1).Metodo1;
Classe1.Destroy;
Classe2 := TClasse2.Create;
//L’implementazione utilizzata è quelle di TClasse2
Classe2.Metodo1;
Classe2.Destroy;
End;
avremo che l’esecuzione della seconda chiamata “Classe1.Metodo1” determinerà l’esecuzione dell’implementazione del metodo nella classe “TClasse1” anche se la variabile “Classe1” fa riferimento ad un oggetto di tipo “TClasse2”.
I metodi dichiarati virtual o dynamic possono essere ridefiniti nelle classi discendenti. Per dichiarare dei metodi come virtual o dynamic occorre specificare dopo la loro dichiarazione le parole chiave virtual o dynamic. A differenza dei metodi static la determinazione dell’implementazione del metodo da utilizzare nella chiamata viene determinata in base al tipo run-time. Per ridefinire un metodo virtual o dynamic occorre specificare, nella classe discendente, un metodo con lo stesso nome del metodo della classe antenato e utilizzare la parola chiave override dopo la sua dichiarazione.
Apportando le modifiche del caso, riprendiamo l’esempio visto in precedenza per i tipi static e vediamo le differenze
Type TClasse1 = Class
Procedure Metodo1;
End;
TClasse2 = Class(TClasse1)
Procedure Metodo1; override;
End;
Var Classe1 : TClasse1;
Classe2 : TClasse2;
Begin
Classe1 := TClasse1.Create;
Classe1.Metodo1;
//L’implementazione utilizzata è quelle di TClasse1
Classe1.Destroy;
Classe1 := TClasse2.Create;
Classe1.Metodo1;
//L’implementazione utilizzata è quelle di TClasse2
TClasse2(Classe1).Metodo1;
Classe1.Destroy;
Classe2 := TClasse2.Create;
Classe2.Metodo1;
//L’implementazione utilizzata è quelle di TClasse2
Classe2.Destroy;
End;
Come ripostato nel commento del codice, la seconda chiamata a “Classe1.Metodo1” utilizzerà l’implementazione di “TClasse2” poichè il tipo run-time al momento della chiamata è “TClasse2”.
Le differenze tra metodi virtuali e dinamici consiste essenzialmente nell’implementazione dellq chiamata al metodo in fase di esecuzione. I metodi viruali sono ottimizzati per velocità, mentre i metodi dinamici per dimensione.
Un’altro tipo interessante di metodo e quello dei metodi astratti. I metodi astratti permettono di definire metodi senza alcuna implementazione del metodo stesso. Ciò risulta utilie quando si vogliono creare delle classi base che stabiliscano l’interfaccia base dei metodi ma che permettano alle classi discendenti di definire l’implementazione di quei metodi. Questo tipo di metodo è un particolare tipo di metodo astratto o dinamico.
Per dichiarare un metoto astratto, occorre specificare dopo le parole chiave virtual o dynamic la praola chiave abstract.
Altri due tipi di metodi importanti nella programmazione ad oggetti sono i metodi costruttori e distruttori. Questi si occupano, come dicono le parole stesse, di creare ed inizializzare un’istanza di classe o di distruggere e liberare la memoria occupata dall’istanza di classe precedentemente creata.
I metodi costruttori sono caratterizzati dalla parola chiave constructor al posto della parola chiave procedure o function. L’implementazione di questi metodi, prevede la creazione dell’istanza di classe allocando memoria nello heap, ed l’inizializzazione automatica a zero dei valori ordinal, a nil dei campi puntatore e classe, l’azzeramento di tutti i campi string. Solitamente all’interno di un metodo costruttore viene prima di tutto chiamato il metodo costruttore ereditato dall’antenato per inizializzare il codice comune, dopo di che viene eseguito il codice necessario ad inizializzare il codice specificao per la classe discendente. Potrebbe capitare che durante l’esecuzione del codice di inizializzazione si generino delle eccezioni; in tal caso verrà eseguito automaticamente il distruttore destroy per disturggere l’oggetto non completato. Nella creazione di un oggetto, occorre chiamare il metodo costruttore facendolo precedere dal nome della classe di appartenenza dell’oggetto che si vuole creare. In tal modo, il metodo costruttore restituirà, al termine della chiamata, un puntatore all’istanza appena creata. Se il metodo costruttore viene chiamato utilizzando un riferimento ad un oggetto, questo non restituisce nulla.
I metodi distruttori seguono le stessa regola dichiarativa dei metodi costruttori tranne per il fatto che utilizzano la parola chiave destructor al posto di constructor. I metodi distruttori si occupano di distruggere l’oggetto e deallocare la memoria da esso occupata. Per chiamare un metodo distruttore bisogna fare riferimento ad un oggetto istanza come per esempio
MioOggetto.Destroy;
La chiamata al metodo destroy produce l’immediata esecuzione del codice contenuto nell’implementazione del metodo destroy stesso. All’interno del metodo distruttore viene eseguito tutto quel codice atto ad eliminare eventuali altre istanze di oggetti incorporati e nella liberazione della memoria da loro occupata. L’ultima istruzione di un metodo destroy , è solitamente una chiamata al metodo destroy ereditato in maniera da eliminare i campi e ripulire la memoria occupata dal codice ereditato. Come detto in precedenza, se durante la creazione di un oggetto viene sollevata una eccezione, viene eseguito il metodo destroy. In tal caso, questo metodo deve essere pronto ad interagire con codice non completamente inizializzato che, in particolare per i campi di tipo class, significa controllare se il cmapo ha valore Nil prima di effettuare la chiamata al metodo destroy della classe di quel campo. Per questo Delphi mette a disposizione il metodo Free definito nella classe TObject che permette di gestire in automatico il controllo sulla presenza di valori Nil prima di eseguire la distruzione dell’oggetto.
Gestori di messaggi
Un altro tipo di metodo messo a disposizione in Delphi è il gestore di messaggi. Un gestore di messaggi sono metodi che rispondono ai messaggi inviati da Windows, da altre applicazioni o dall’applicazione che stiamo realizzando. Esistino messaggi predefiniti e messaggi che possono essere dichiarati dallo sviluppatore.
Per dichiarare un gestore di messaggi, si include la direttiva message dopo la dichiarazione del metodo seguito da un identificatore integer costante di messaggio il cui valore deve essere compreso tra 1 e 49151. Alcuni dei messaggi utilizzati da Windows e quelli utilizzati dai controlli della VCL sono definiti nella unit messages. Nella definizione di ogni messaggio è necessario dichiarare una costante contenente l’ID del messaggio ed una struttura (un record) che descriva il contenuto del messaggio. Ecco la dichiarazione di un gestore di messaggio er il messaggio WM_CHAR
Type TTextBox = Class(TCustomControl)
Private
Procedure WMChar(Var Message : TWMChar); message
WM_CHAR;
…
End;
Il codice seguente, ripreso dal manuale del linguaggio, mostra come implementare il gestore di evento dichiarato in precedenza affinchè venga eseguito un codice particolare alla pressione del tasto invio in un controllo di tipo TTextBox e l’esecuzione del codice ereditato per tutti gli altri tasti
Procedure TTextBox.WMChar(Var Message : TWMChar);
Begin
If Chr(Message.ChrCode) = #13 then
ProcessEnter
Else
Inherited;
End;
tramite l’istruzione Inherited viene ricercato nelle classi antenato una implementazione del gestore per quel messaggio e qualora non ne sia disponibile una, viene eseguito il metodo gestore predefinito DeafultHandler definito nella classe TObject. Per richiamare un gestore di messaggio, si utilizza il metodo Dispatch dichiarato nella classe TObject. Questo metodo richiede che gli venga passato un record il cui primo campo sia di tipo cardinal e contenga l’ID del messaggio.
Se vuoi aggiornamenti su Classi ed Oggetti: i metodi inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
I Video di HTML.it
Tutto su Async/Await di C# e VB
In questo video esamineremo le nuove parole chiave async e await di C# 5 e VB 11 dalle basi fino a […]