2015-01-30 14 views
7

Ich lese das Buch von Nick Hodges "Codierung in Delphi" und ich versuche, die Verwendung der Schnittstelle zu verstehen. In einer Einheit habe ich Asimple Schnittstelle setzen:Versuchen Sie, Delphi Interfaces zu verstehen

unit INameInterface; 

interface 

type 
    IName = interface 
    ['{CE5E1B61-6F44-472B-AE9E-54FF1CAE0D70}'] 
    function FirstName: string; 
    function LastName: string; 
    end; 

implementation 

end. 

und in einer anderen Einheit habe ich die Implementierung dieser Schnittstelle setzen, nach dem Buch Beispiel:

unit INameImplementation; 

interface 

uses 
    INameInterface; 

type 
    TPerson = class(TInterfacedObject, IName) 
    protected 
     function FirstName: string; 
     function LastName: string; 
    end; 

implementation 

{ TPerson } 

function TPerson.FirstName: string; 
begin 
    Result := 'Fred'; 
end; 

function TPerson.LastName: string; 
begin 
    Result := 'Flinstone'; 
end; 

end. 

An dieser Stelle ich Ich habe eine einfache VCL-Formularanwendung erstellt, um das von mir erstellte Objekt zu verwenden. Der Formularcode lautet wie folgt:

unit main; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
    System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, 
    Vcl.StdCtrls, INameImplementation; 

type 
    TfrmMain = class(TForm) 
    lblFirtName: TLabel; 
    lblLastName: TLabel; 
    txtFirstName: TStaticText; 
    txtLastName: TStaticText; 
    btnGetName: TButton; 
    procedure btnGetNameClick(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    private 
    Person: TPerson; 
    public 
    { Public declarations } 
    end; 

var 
    frmMain: TfrmMain; 

implementation 

{$R *.dfm} 

procedure TfrmMain.FormCreate(Sender: TObject); 
begin 
    txtFirstName.Caption := ''; 
    txtLastName.Caption := ''; 
end; 

procedure TfrmMain.btnGetNameClick(Sender: TObject); 
begin 
    txtFirstName.Caption := ... 
end; 

end. 

Meine Frage ist das: Wie kann ich die Schnittstelle verwenden? Die beiden Funktionen sind als geschützt deklariert, also wie kann ich über das Formular darauf zugreifen? Ich muss sie als öffentlich definieren oder sollte ich die INAMEInterface-Schnittstelleneinheit verwenden? Ich bin schrecklich verwirrt über Schnittstellen !!!

Eros

+1

Ein großartiges Beispiel dafür, wie Schnittstellen verwendet werden ... Angenommen, Sie haben eine DLL mit einem Objekt darin, das Sie auch im aufrufenden Prozess verwenden möchten. Sie können Objekte nicht über die DLL-Grenzen hinweg übergeben, aber Sie können Schnittstellen übergeben (sofern die Elemente auch sicher sind, z. B. WideString anstelle von String). Dann instanziieren Sie das Objekt innerhalb der DLL und übergeben eine Schnittstellenreferenz dieses Objekts von der DLL zurück an die aufrufende Anwendung - dann kann die aufrufende Anwendung mit dieser Schnittstelle auf die gleiche Weise interagieren, als ob Sie das Objekt direkt aufrufen würden. –

+0

@Jerry Das ist eher ein Implementierungsproblem mit binären Interop. Ich denke, Schnittstellen sind ein tieferes Konzept. –

Antwort

8

Im Wesentlichen gibt es drei Dinge für Sie zu wissen, über was Sie bereits Verständnis gezeigt haben.

1. Wie Methoden einer Schnittstelle

anrufen Wenn Sie einen Verweis auf eine Schnittstelle haben, dann können Sie Methoden aufrufen, so wie man es auf einer Klassenreferenz:

var 
    Name: IName; 
.... 
Writeln(Name.FirstName); 
Writeln(Name.LastName); 

2. So erhalten Sie Schnittstellenreferenzen

Normalerweise tun Sie dies, indem Sie eine Klasse instanziieren, die die Schnittstelle implementiert, die Sie verwenden möchten:

Es gibt andere Möglichkeiten, Schnittstellenreferenzen zu erhalten, aber lassen Sie diese für jetzt auf eine Seite.

3. Wie um passieren Schnittstellen

Sie werden vielleicht nicht jedes Mal, wenn eine Schnittstelle verwenden, müssen Sie ein neues Objekt erstellen möchten. So können Sie andere Parteien dazu bringen, Ihnen die Schnittstelle zu übergeben. Zum Beispiel Schnittstellen als Methodenparameter können übergeben werden:

procedure Foo(Name: IName); 
begin 
    // use Name as before 
end; 

Sie Interface-Referenzen über Funktionsaufrufe und Eigenschaften erhalten etc.


Die beiden Funktionen werden als protected erklärt, so wie kann ich auf sie aus dem Formular zugreifen?

Nun, sie sind im implementierenden Objekt protected deklariert. Sie werden jedoch nicht über das implementierende Objekt darauf zugreifen. Sie werden über die Schnittstelle darauf zugreifen. Das bedeutet, dass die Sichtbarkeit im implementierenden Objekt aus Sicht der Schnittstelle nicht relevant ist.

Ihre Formulareinheit verweist auf INameImplementation, die zum Erstellen des Objekts benötigt wird, das die Schnittstelle implementiert. Sie müssen auch INameInterface verwenden, damit Ihr Code die Schnittstelle selbst sehen kann.

Dieses Beispiel ist noch nicht sehr leistungsfähig, weil Sie immer noch den Typ des implementierenden Objekts sehen können. Aber stellen Sie sich vor, wenn das vor Ihnen verborgen war und alles, was Sie sehen konnten, war eine Funktion, die einen IName zurückgab. Wenn Sie diesen Punkt erreichen, können Schnittstellen ihr Potenzial erreichen.

+0

Da ist sehr David. Nur noch eine Frage: also muss ich INameInterface und INameImplementation in die uses-Klausel der Haupteinheit aufnehmen. Ist das die normale Verwendung dieser Art von Objekten? – Eros

+0

Es gibt viel mehr über Interfaces zu sagen, aber ich habe versucht, bei den Grundlagen zu bleiben. Ich vertraue darauf, dass Nick's Buch viel mehr sagt. –

+0

@Eros: Alle Schnittstellenverbraucher sollten nur auf die Schnittstelleneinheit verweisen. Dependency-Injektion ist eine natürliche Ergänzung für diese Art der Codierung. – whosrdaddy

Verwandte Themen