Einzelnen Beitrag anzeigen

viakt133

Registriert seit: 16. Feb 2010
18 Beiträge
 
Lazarus
 
#3

Re: Auf Interfaces zugreifen?

  Alt 18. Feb 2010, 18:17
Zitat von Panthrax:
Delphi-Quellcode:
var
  I: IAppInterface;
begin
  I := TAppIntfImpl.Create;
    // u.U. kann auch soetwas gewollt sein: I := TKlasse.Create as ISchnittstelle;
end;
Danke erst mal für die echt schnelle Antwort!

Jetzt tut sich aber ein weiteres Problem auf:

Wenn ich zum Instantiieren wieder, wie in der Antwort geschrieben, TAppIntfImpl.Create aufrufe, wozu dann das Interface?

Dann müsste ich ja das AppInterface in der Implementationsunit instantiieren, was ich jetzt auch gemacht habe und zwar so, wie in der geänderten Unit UAppIntfImpl:

Delphi-Quellcode:
unit UAppIntfImpl;

interface

uses
  Classes, Sysutils, Dialogs, UAppIntf;

type
  TAppIntfImpl = class(TInterfacedObject, IAppInterface)
    procedure DoSomething;
  end;

var
  //Diese Variable ist nun meine Klasseninstanz
  AppInterface: TAppIntfImpl;

implementation

{ TAppIntfImpl }

procedure TAppIntfImpl.DoSomething;
begin
  ShowMessage('the Interfaced method');
end;

initialization
  AppInterface := TAppIntfImpl.Create;

finalization
  AppInterface.Free;

end.
Was will ich aber nun haben?

Ich will das Interface ansprechen, als ob es die Klasse wäre.

So könnte ich dann mit exakt demselben Zugriff, ohne den unten stehenden Quelltext ändern zu müssen,
die Methode TAppIntfImpl.DoSomething ändern und die von jetzt an die geänderte Methode aufrufen.

Delphi-Quellcode:
var
  I: IAppInterface;
begin
  //heute:
  I := TAppIntfImpl.Create;
  //und morgen
  I := TAppIntfImpl2.Create;
end;
Ich habe meine Unit deshalb in diese Form hier geändert:

Delphi-Quellcode:
unit UAppIntfUser;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UAppIntf, StdCtrls, UAppIntfImpl;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    FInterfaceExists: Boolean;
  public
    FInterface: IAppInterface;
    FInterfaced: TAppIntfImpl;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if FInterfaceExists then
  AppInterface.DoSomething;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FInterfaceExists := true;
  FInterfaced := AppInterface;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FInterfaced.Free;
end;

end.
Wenn ich das starte, erhalte ich, was ich will, die Interfaced-Methode wird aufgerufen.
Allerdings erhalte ich eine Exception mit der Meldung "ungültige Zeigeroperation".

Wenn ich jedoch FInterfaced.Free im finalization Abschnitt der Unit UAppIntfImpl nicht aufrufe, kommt diese Exception nicht.

Habe deshalb probeweise auch die Instantiierung im Initialization Abschnitt meiner Implementations Unit UAppIntfImpl entfernt und ich kann trotzdem auf die Klasse zugreifen.

Wo gibt es weiterführende Literatur zum Thema?

Nun muss ich wahrscheinlich immer den Typ der Klasse, die an das Interface angeschlossen werden soll, mitschleppen? Oder gibt es noch eine elegantere Möglichkeit. Wenn ich ein anderes Appinteface
bauen will, wo zb. in der Methode FInterfaced.DoSomething der WinAmp augerufen wird und in einer anderen gleich aufgebauten Klasse der Windows Media Player. Gibt es da noch einen eleganteren Weg?


.
  Mit Zitat antworten Zitat