![]() |
Interface, Einsteigerproblem?
Hallo,
ich wollte mal probieren, ob ich das Interface-Konzept von Delphi für meine Gedanken nutzbar machen kann. Dazu wollte ich ausgewählten abgeleiteten Klassen ein Interface zuordnen. Mein Gedankengang ist, dass ich so vielleicht mit den Basisklassen weiterarbeiten kann und dann über eine Methode testen kann, ob das Interface in diesem Objekt hinterlegt ist:
Delphi-Quellcode:
Naja, nutze ich TTestClass zur Verwaltung, Null Probleme. Aber der Vorteil ergibt sich doch erst, wenn ich in der TBaseClass nutzen könnten, nur wie?
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type ITest1 = interface procedure Test1; end; ITest2 = interface procedure Test2; end; TBaseClass = class(TInterfacedObject, ITest1) public procedure Test1; virtual; end; TTestClass = class(TBaseClass, ITest2) public procedure Test2; procedure Test1; override; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} { TTestClass } procedure TTestClass.Test1; begin inherited; ShowMessage('TTestClass.Test1;'); end; procedure TTestClass.Test2; begin ShowMessage('TTestClass.Test2;'); end; { TBaseClass } procedure TBaseClass.Test1; begin ShowMessage('TBaseClass.Test1;'); end; procedure TForm1.Button1Click(Sender: TObject); //var aClass: TTestClass; var aClass: TBaseClass; aInterface1: ITest1; aInterface2: ITest2; begin aClass := TTestClass.Create; aInterface1 := ITest1(aClass); aInterface2 := ITest2(aClass); aInterface1.Test1; aInterface2.Test2; end; end. |
Re: Interface, Einsteigerproblem?
Ich versteht zwar noch nicht so ganz was du im Detail willst, aber ein paar Änderungen
Delphi-Quellcode:
Eigenlich sind Interface's dazu da verschieden Klassen eine gemeinsamme Menge zu geben.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type ITest1 = interface an dieser Stelle Strg+Shift+G drücken procedure Test1; end; ITest2 = interface an dieser Stelle Strg+Shift+G drücken procedure Test2; end; TBaseClass = class(TInterfacedObject, ITest1) public procedure Test1; virtual; end; TTestClass = class(TBaseClass, ITest2) public procedure Test2; procedure Test1; override; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} { TTestClass } procedure TTestClass.Test1; begin inherited; if Self is ITest2 then (Self as ITest2).Test2; // meinst du Sowas ShowMessage('TTestClass.Test1;'); end; procedure TTestClass.Test2; begin ShowMessage('TTestClass.Test2;'); end; { TBaseClass } procedure TBaseClass.Test1; begin ShowMessage('TBaseClass.Test1;'); end; procedure TForm1.Button1Click(Sender: TObject); //var aClass: TTestClass; var aClass: TBaseClass; aInterface1: ITest1; aInterface2: ITest2; begin aClass := TTestClass.Create; aInterface1 := aClass as ITest1; // verwendet QueryInterface aInterface2 := aClass as ITest2; // verwendet QueryInterface aInterface1.Test1; aInterface2.Test2; end; end. z.B.
Delphi-Quellcode:
Anwendung
type
ITest = interface (IUnknown) Strg+Shift+G procedure Test1; end; TMyEdit = class (TEdit, ITest) ... end; TMyButton = class (TButton, ITest) ... end; TMyLabel = class (TLabel, ITest) ... end;
Delphi-Quellcode:
ODER
if Controls[i] is ITest then // Unterstütz dieses Control Test
(txtTest as ITest).Test; Man verwendet sie als einheitliche Schnittstelle in Dll's -> COM |
Re: Interface, Einsteigerproblem?
Also ist es so richtig?
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type ITest1 = interface ['{BC490D6F-306F-4FC5-AF6A-D76B39658B9F}'] procedure Test1; end; ITest2 = interface ['{BDCB2821-FC57-4729-A1C0-9CEF3A28F72A}'] procedure Test2; end; TBaseClass = class(TInterfacedObject, ITest1) public procedure Test1; virtual; end; TTestClass = class(TBaseClass, ITest2) public procedure Test2; procedure Test1; override; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} { TTestClass } procedure TTestClass.Test1; begin inherited; ShowMessage('TTestClass.Test1;'); end; procedure TTestClass.Test2; begin ShowMessage('TTestClass.Test2;'); end; { TBaseClass } procedure TBaseClass.Test1; begin ShowMessage('TBaseClass.Test1;'); end; procedure TForm1.Button1Click(Sender: TObject); var aClass: TBaseClass; aInterface1: ITest1; aInterface2: ITest2; begin aClass := TTestClass.Create; if aClass.QueryInterface(StringToGuid('{BDCB2821-FC57-4729-A1C0-9CEF3A28F72A}'),aInterface2) = 0 then aInterface2.Test2; if aClass.QueryInterface(StringToGuid('{BC490D6F-306F-4FC5-AF6A-D76B39658B9F}'),aInterface1) = 0 then aInterface1.Test1; end; end. |
Re: Interface, Einsteigerproblem?
Warum so umständlich???
Delphi-Quellcode:
Übrignes wird das vom Compiler in was ähnliches umgesetzt wie du geschrieben hast.
procedure TForm1.Button1Click(Sender: TObject);
var aClass: TBaseClass; aInterface1: ITest1; aInterface2: ITest2; begin aClass := TTestClass.Create; if aClass is ITest2 then // <-- hier dahinter steht ein QueryInterface begin aInterface2 := aClass as ITest2; aInterface2.Test2; end; if aClass is ITest1 then begin aInterface1 := aClass as ITest1; aInterface1.Test1; end; end; |
Re: Interface, Einsteigerproblem?
Den Vergleich mit is mag Delphi gar nicht:
Zitat:
|
Re: Interface, Einsteigerproblem?
:gruebel:
Das muss ich mir mal genauer anschauen! Ich muss jetzt aber mal weg! Das wird erst gegen 17:00, falls ich es nicht vergesse! |
Re: Interface, Einsteigerproblem?
Ich habe meinen Code jetzt noch mal ein wenig abgespeckt:
Delphi-Quellcode:
Damit ist er jetzt eigentlich sehr einfach geworden. Wenn Du aber trotzdem nachschauen könntest, wäre es schön. Interessieren würde es mich!
type
ITest1 = interface ['{BC490D6F-306F-4FC5-AF6A-D76B39658B9F}'] procedure Test1; end; ITest2 = interface ['{BDCB2821-FC57-4729-A1C0-9CEF3A28F72A}'] procedure Test2; end; TBaseClass = class(TInterfacedObject, ITest1) public procedure Test1; virtual; end; TTestClass = class(TBaseClass, ITest2) public procedure Test2; procedure Test1; override; end; ... procedure TForm1.Button1Click(Sender: TObject); var aClass: TBaseClass; aInterface1: ITest1; aInterface2: ITest2; begin aClass := TBaseClass.Create; if aClass.QueryInterface(ITest1,aInterface2) = S_OK then aInterface2.Test2; if aClass.QueryInterface(ITest2,aInterface1) = S_OK then aInterface1.Test1; end; |
Re: Interface, Einsteigerproblem?
Ein Fehler meinerseits!
Vergiss den is-Operator. Deine Variante mit den QueryInterface ist ok. Das biete ich an:
Delphi-Quellcode:
Ich verwende beide, je nachdem.
var aClass: TBaseClass;
aInt : ITest2; begin // aClass := TBaseClass.Create; aClass := TTestClass.Create; // 1. Variante if aClass.GetInterface(ITest2, aInt) then aInt.Test2 else ShowMessage('ITest2 nicht existent!'); // 2. Variante try (aClass as ITest1).Test1; except on E:EIntfCastError do ShowMessage('ITest1 nicht existent!'); end; try (aClass as ITest2).Test2; except on E:EIntfCastError do ShowMessage('ITest2 nicht existent!'); end; end; |
Re: Interface, Einsteigerproblem?
Danke!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz