Definizione e implementazione delle interfacce in Delphi

Nel Delphi, "interfaccia" ha due significati distinti. Nel OOP gergo, puoi pensare a un'interfaccia come a una classe senza implementazione. Nella sezione dell'interfaccia di definizione dell'unità Delphi viene utilizzata per dichiarare qualsiasi sezione pubblica di codice che appare in un'unità. Questo articolo spiegherà le interfacce da una prospettiva OOP.

Se hai intenzione di creare un'applicazione solida in modo che il tuo codice sia mantenibile, riutilizzabile e flessibile OOP la natura di Delfi ti aiuterà a guidare il primo 70% del percorso. Definire le interfacce e implementarle aiuterà con il restante 30%.

Classi astratte

Puoi pensare a un'interfaccia come a una classe astratta con tutta l'implementazione eliminata e tutto ciò che non è pubblico rimosso. Una classe astratta in Delphi è una classe che non può essere istanziata: non è possibile creare un oggetto da una classe contrassegnata come astratta.

Diamo un'occhiata a una dichiarazione di interfaccia di esempio:

genere
IConfigChanged = interfaccia[ '{0D57624C-CDDE-458B-A36C-436AE465B477}']
procedura ApplyConfigChange;
fine;
instagram viewer

Il IConfigChanged è un'interfaccia. Un'interfaccia è definita in modo molto simile a una classe, al posto di "classe" viene utilizzata la parola chiave "interfaccia". Il valore Guid che segue la parola chiave dell'interfaccia viene utilizzato dal compilatore per identificare in modo univoco l'interfaccia. Per generare un nuovo valore GUID, basta premere Ctrl + Maiusc + G nell'IDE Delphi. Ogni interfaccia definita richiede un valore Guid univoco.

Un'interfaccia in OOP definisce un'astrazione - un modello per una classe effettiva che implementerà l'interfaccia - che implementerà i metodi definiti dall'interfaccia. Un'interfaccia in realtà non fa nulla, ha solo una firma per l'interazione con altre classi o interfacce (implementanti).

L'implementazione dei metodi (funzioni, procedure e proprietà Get / Set metodi) viene eseguita nella classe che implementa l'interfaccia. Nella definizione dell'interfaccia, non ci sono sezioni di ambito (private, pubbliche, pubblicate, ecc.) Tutto è pubblico. Un tipo di interfaccia può definire funzioni, procedure (che alla fine diventeranno metodi della classe che implementa l'interfaccia) e proprietà. Quando un'interfaccia definisce una proprietà, deve definire i metodi get / set - le interfacce non possono definire le variabili.

Come per le classi, un'interfaccia può ereditare da altre interfacce.

genere
IConfigChangedMore = interfaccia(IConfigChanged)
procedura ApplyMoreChanges;
fine;

Programmazione

Molti sviluppatori Delphi quando pensano alle interfacce pensano alla programmazione COM. Tuttavia, le interfacce sono solo una funzionalità OOP del linguaggio, non sono specificamente legate a COM. Le interfacce possono essere definite e implementate in un'applicazione Delphi senza toccare COM.

Implementazione

Per implementare un'interfaccia è necessario aggiungere il nome dell'interfaccia all'istruzione class, come in:

genere
TMainForm = classe(TForm, IConfigChanged)
pubblico
procedura ApplyConfigChange;
fine;

Nel codice sopra un modulo Delphi chiamato "MainForm" implementa l'interfaccia IConfigChanged.

avvertimento: quando una classe implementa un'interfaccia, deve implementare tutti i suoi metodi e proprietà. Se non si riesce / si dimentica di implementare un metodo (ad esempio: ApplyConfigChange) un errore di compilazione "Identificatore non dichiarato E2003: 'ApplyConfigChange'" si verificherà.
avvertimento: se provi a specificare l'interfaccia senza il valore GUID riceverai: "Il tipo E2086 'IConfigChanged' non è ancora completamente definito".

Esempio

Si consideri un'applicazione MDI in cui è possibile visualizzare all'utente diversi moduli contemporaneamente. Quando l'utente modifica la configurazione dell'applicazione, la maggior parte dei moduli deve aggiornare il proprio display: mostra / nasconde alcuni pulsanti, aggiorna i sottotitoli delle etichette, ecc. Avresti bisogno di un modo semplice per avvisare tutti i moduli aperti che si è verificato un cambiamento nella configurazione dell'applicazione. Lo strumento ideale per il lavoro era un'interfaccia.

Ogni modulo che deve essere aggiornato quando le modifiche alla configurazione implementeranno IConfigChanged. Poiché la schermata di configurazione viene visualizzata in modo modale, quando si chiude il codice successivo si assicura che tutti i moduli di implementazione IConfigChanged vengano notificati e che ApplyConfigChange venga chiamato:

procedura DoConfigChange ();
var
cnt: intero;
icc: IConfigChanged;
inizio
per cnt: = 0 per -1 + Schermo. FormCount fare
inizio
Se Supporta (schermo. Forms [cnt], IConfigChanged, icc) poi
ICC. ApplyConfigChange;
fine;
fine;

I supporti funzione (definito in Sysutils.pas) indica se un determinato oggetto o interfaccia supporta un'interfaccia specificata. Il codice scorre attraverso lo schermo. Raccolta moduli (dell'oggetto TScreen): tutti i moduli attualmente visualizzati nell'applicazione. Se un modulo Schermo. Forme [cnt] supporta l'interfaccia, Supports restituisce l'interfaccia per l'ultimo parametro parametro e restituisce true.

Pertanto, se il modulo implementa IConfigChanged, la variabile icc può essere utilizzata per chiamare i metodi dell'interfaccia così come implementati dal modulo. Si noti, ovviamente, che ogni modulo può avere la propria diversa implementazione della procedura ApplyConfigChange.

antenati

Qualsiasi classe definita in Delphi deve avere un antenato. TObject è l'ultimo antenato di tutti gli oggetti e componenti. L'idea sopra si applica anche alle interfacce, IInterface è la classe base per tutte le interfacce. IInterface definisce 3 metodi: QueryInterface, _AddRef e _Release.

Ciò significa che il nostro IConfigChanged ha anche quei 3 metodi, ma non li abbiamo implementati. Questo perché TForm eredita da TComponent che implementa già la IInterface per te! Quando si desidera implementare un'interfaccia in una classe che eredita da TObject, assicurarsi invece che la classe erediti da TInterfacedObject. Poiché TInterfacedObject è un TObject che implementa IInterface. Per esempio:

TMyClass = classe(TInterfacedObject, IConfigChanged)
procedura ApplyConfigChange;
fine;

In conclusione, IUnknown = IInterface. IUnnown è per COM.

instagram story viewer