Definere og implementere grensesnitt i Delphi

I Delphi, "grensesnitt" har to forskjellige betydninger. I OOP jargon, kan du tenke på et grensesnitt som en klasse uten implementering. I Delphi enhetsdefinisjonsgrensesnitt blir seksjoner brukt til å deklarere offentlige koder som vises i en enhet. Denne artikkelen vil forklare grensesnitt fra et OOP-perspektiv.

Hvis du ønsker å lage en bunnsolid applikasjon på en måte som koden din er vedlikeholdbar, gjenbrukbar og fleksibel OOP natur av Delphi vil hjelpe deg å kjøre de første 70% av ruten. Å definere grensesnitt og implementere dem vil hjelpe med de resterende 30%.

Abstrakte klasser

Du kan tenke på et grensesnitt som en abstrakt klasse med all implementeringen strippet ut og alt som ikke er offentlig fjernet. En abstrakt klasse i Delphi er en klasse som ikke kan instantieres - du kan ikke opprette et objekt fra en klasse merket som abstrakt.

La oss se på et eksempel på en grensesnitterklæring:

type
IConfigChanged = grensesnitt[ '{0D57624C-CDDE-458B-A36C-436AE465B477}']
fremgangsmåte ApplyConfigChange;
slutt;
instagram viewer

De IConfigChanged er et grensesnitt. Et grensesnitt er definert omtrent som en klasse, søkeordet "grensesnitt" brukes i stedet for "klasse". Veiledningsverdien som følger grensesnittnøkkelordet, brukes av kompilatoren til å identifisere grensesnittet på en unik måte. For å generere en ny GUID-verdi, trykk bare Ctrl + Shift + G i Delphi IDE. Hvert grensesnitt du definerer trenger en unik veiledningsverdi.

Et grensesnitt i OOP definerer en abstraksjon - en mal for en faktisk klasse som skal implementere grensesnittet - som vil implementere metodene definert av grensesnittet. Et grensesnitt gjør faktisk ikke noe, det har bare en signatur for interaksjon med andre (implementerende) klasser eller grensesnitt.

Implementeringen av metodene (funksjoner, prosedyrer og Get / Set-metoder) for eiendommer gjøres i klassen som implementerer grensesnittet. I grensesnittdefinisjonen er det ingen omfangsseksjoner (privat, offentlig, publisert osv.) Alt er offentlig. En grensesnitttype kan definere funksjoner, prosedyrer (som til slutt blir metoder i klassen som implementerer grensesnittet) og egenskaper. Når et grensesnitt definerer en egenskap, må det definere get / set-metodene - grensesnitt kan ikke definere variabler.

Som med klasser, kan et grensesnitt arve fra andre grensesnitt.

type
IConfigChangedMore = grensesnitt(IConfigChanged)
fremgangsmåte ApplyMoreChanges;
slutt;

programmering

De fleste Delphi-utviklere når de tenker på grensesnitt de tenker på COM-programmering. Grensesnitt er imidlertid bare en OOP-funksjon på språket - de er ikke bundet til COM spesifikt. Grensesnitt kan defineres og implementeres i en Delphi-applikasjon uten å berøre COM i det hele tatt.

Gjennomføring

For å implementere et grensesnitt må du legge til navnet på grensesnittet til klassesetningen, som i:

type
TMainForm = klasse(TForm, IConfigChanged)
offentlig
fremgangsmåte ApplyConfigChange;
slutt;

I koden over implementerer et Delphi-skjema med navnet "MainForm" IConfigChanged-grensesnittet.

Advarsel: Når en klasse implementerer et grensesnitt, må den implementere alle dens metoder og egenskaper. Hvis du ikke klarer / glemmer å implementere en metode (for eksempel: ApplyConfigChange), er det en feil i kompileringstiden "E2003 Udeklarert identifikator: 'ApplyConfigChange'" vil skje.
Advarsel: hvis du prøver å spesifisere grensesnittet uten GUID-verdien du vil motta: "E2086 Type 'IConfigChanged' er ennå ikke fullstendig definert".

Eksempel

Vurder en MDI-applikasjon der flere skjemaer kan vises for brukeren samtidig. Når brukeren endrer applikasjonskonfigurasjonen, trenger de fleste skjemaer å oppdatere skjermen - vise / skjule noen knapper, oppdatere etiketttekst osv. Du trenger en enkel måte å varsle alle åpne skjemaer om at en endring i applikasjonskonfigurasjonen har skjedd. Det ideelle verktøyet for jobben var et grensesnitt.

Hvert skjema som må oppdateres når konfigurasjonsendringene implementerer IConfigChanged. Siden konfigurasjonsskjermen vises modalt, når den lukker neste kode, sikrer du at alle IConfigChanged implementeringsformer blir varslet og ApplyConfigChange heter:

fremgangsmåte DoConfigChange ();
Var
cnt: heltall;
icc: IConfigChanged;
begynne
til cnt: = 0 til -1 + skjerm. FormCount gjøre
begynne
hvis Støtter (skjerm. Skjemaer [cnt], IConfigChanged, icc) deretter
ICC. ApplyConfigChange;
slutt;
slutt;

Støttene funksjon (definert i Sysutils.pas) indikerer om et gitt objekt eller grensesnitt støtter et spesifisert grensesnitt. Koden itererer gjennom skjermen. Skjemasamling (av TScreen-objektet) - alle skjemaene som for øyeblikket vises i applikasjonen. Hvis et skjema Skjerm. Skjemaer [CNT] støtter grensesnittet, Supports returnerer grensesnittet for den siste parameterparameteren og returnerer true.

Derfor, hvis skjemaet implementerer IConfigChanged, kan icc-variabelen brukes til å kalle metodene til grensesnittet som implementert av skjemaet. Merk selvfølgelig at enhver form kan ha sin egen forskjellige implementering av ApplyConfigChange-prosedyren.

forfedre

Enhver klasse du definerer i Delphi må ha en stamfar. TObject er den ultimate stamfaren til alle objekter og komponenter. Ovenstående ide gjelder også for grensesnitt, IInterface er baseklassen for alle grensesnitt. IInterface definerer tre metoder: QueryInterface, _AddRef og _Release.

Dette betyr at IConfigChanged også har de tre metodene, men vi har ikke implementert disse. Dette fordi TForm arver fra TComponent som allerede implementerer IInterface for deg! Når du vil implementere et grensesnitt i en klasse som arver fra TObject, må du sørge for at klassen arver fra TInterfacedObject i stedet. Siden TInterfacedObject er et TObject som implementerer IInterface. For eksempel:

TMyClass = klasse(TInterfacedObject, IConfigChanged)
fremgangsmåte ApplyConfigChange;
slutt;

Avslutningsvis IUnbekjent = IInterface. IUnbekjent er for COM.

instagram story viewer