AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage zu Interfaces

Ein Thema von Oracle · begonnen am 26. Nov 2007 · letzter Beitrag vom 29. Nov 2007
Antwort Antwort
Seite 2 von 2     12   
Oracle
(Gast)

n/a Beiträge
 
#11

Re: Verständnisfrage zu Interfaces

  Alt 26. Nov 2007, 16:31
Ok das ist ne Menge Input ich muss mir das mal im Detail anschauen, und darüber meditieren
  Mit Zitat antworten Zitat
Oracle
(Gast)

n/a Beiträge
 
#12

Re: Verständnisfrage zu Interfaces

  Alt 26. Nov 2007, 16:48
@xaromz

Warum implementierst du bei Kamera1 in deinem Beispiel nicht einfach beide Interfaces, sondern erbst Kamera und implementierst das Interface ICamera1?

Ich will eigenlich für jeden Hersteller eine eigene Klasse, um die Übersicht zu behalten. Diese sollen alle das gleiche Interface implementieren. Vererbung der Methoden einer Oberklasse bring mir im Prinzip nix, da die Implementierung der einzelnen Methoden bei jedem Kamerahersteller komplett anders ist.
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#13

Re: Verständnisfrage zu Interfaces

  Alt 26. Nov 2007, 18:06
Hallo,
Zitat von Oracle:
Warum implementierst du bei Kamera1 in deinem Beispiel nicht einfach beide Interfaces, sondern erbst Kamera und implementierst das Interface ICamera1?

Ich will eigenlich für jeden Hersteller eine eigene Klasse, um die Übersicht zu behalten. Diese sollen alle das gleiche Interface implementieren. Vererbung der Methoden einer Oberklasse bring mir im Prinzip nix, da die Implementierung der einzelnen Methoden bei jedem Kamerahersteller komplett anders ist.
nun, das war ja nur ein Beispiel. Wenn die tatsächliche Implementierung immer unterschiedlich ist, dann brauchst Du natürlich auch verschiedene Klassen. Möglicherweise kannst Du aber trotzdem eine Superklasse erstellen, die einige Gemeinsamkeiten zusammenfasst. Ob das geht, musst Du aber natürlich selbst wissen.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Oracle
(Gast)

n/a Beiträge
 
#14

Re: Verständnisfrage zu Interfaces

  Alt 26. Nov 2007, 19:24
Alles klar, ich dachte das hätte vielleicht noch einen Hintegrund, der mir im Verborgenen geblieben ist.
Aber danke für die hilfreichen Hinweise!
  Mit Zitat antworten Zitat
Benutzerbild von LoCrux
LoCrux

Registriert seit: 5. Mär 2007
Ort: Gwang-Yang-City
48 Beiträge
 
Delphi 2009 Enterprise
 
#15

Re: Verständnisfrage zu Interfaces

  Alt 29. Nov 2007, 12:34
Hi @All,

noch 'n bissl was zur "Schönheit/Korrektheit".

Hier mal ein Beispiel wie eine meiner Interface Deklarationen aussieht!!

Delphi-Quellcode:
  IUpdater = Interface(IInterface)
    ['{2EA0113C-2BE8-443A-86BE-1B6E40573772}'] //GUID (Global Unique Identifier)
    //-- protected --//
    procedure SetInterfacedOwner(AOwner:TObject); stdcall;
    function GetInterf:IUpdater;
    procedure Call(Sender:TObject); stdcall;
    procedure CallOwner; stdcall;
    procedure RaiseError(Sender:TObject;cid:TID;eid:TErrorID); stdcall;
    function GetCallerID:TID; stdcall;
    function GetActionID:TActionID; stdcall;
    procedure SetActionID(act:TActionID); stdcall;
    function GetCallerAction:TActionID; stdcall;
    procedure RestoreLastAction; stdcall;
    function GetInterfacedObjectOwner:TObject; stdcall;
    function RequestPosition(var px,py:Double;posreq:TPositionRequest;targetID:TID):boolean; stdcall;
    function RequestMainMaxArr(var arr:TMinMaxXYArr; targetID:TID):boolean; stdcall;
    property ActionID:TActionID read GetActionID write SetActionID;
    //-- public !! --//
    property Updater:IUpdater read GetInterf; // referst to self.IUpdater interface
    property InterfacedObjectOwner:TObject read GetInterfacedObjectOwner;
  end;
Zusätzlich hab ich noch zwei Funktionen die ganz Praktisch sind.

Delphi-Quellcode:
function CheckInterface(Caller:TObject;var Intf:IUpdater):Boolean;
begin
  if (Caller<>NIL) then result := Caller.GetInterface(IUpdater,Intf);
end;

// Checks if the caller also has the interface IUpdater and if "I'm" the owner
// If yes it returns true and the Pointer to the interface in "var intf:IUpdater"
function CheckInterface_DoIOwn(Caller,Receiver:TObject;var Intf:IUpdater):Boolean;
begin
  result := false;
  if (Receiver<>NIL)
  then if CheckInterface(Caller,Intf)
       then result := (Intf.InterfacedObjectOwner=Receiver);
end;
und hier mal ein Beispiel für die Definition einer Basisklasse

Delphi-Quellcode:
//----------------------------------------------------------------------------//
// TInterfacedCollectionItem = CLASS(TCollectionItem,IUpdater) //
//----------------------------------------------------------------------------//

  TInterfacedCollectionItem = CLASS(TCollectionItem,IUpdater)
  private
    FOwnerUpInt : IUpdater;
    FOwnerUpIntExists : BOOLEAN;
    FInterfacedOwner : TObject;
    FID : TID;
    FActionID : TActionID;
    FActionRead : Boolean;
  protected
    //-- Interface IInterface --//
    function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
    function _AddRef: Integer; virtual; stdcall;
    function _Release: Integer; virtual; stdcall;
    //-- Interface IUpdater --//
    procedure SetInterfacedOwner(AOwner:TObject); virtual; stdcall;
    function GetInterf:IUpdater;
    procedure Call(Sender:TObject); virtual; stdcall;
    procedure CallOwner; virtual; stdcall;
    procedure RaiseError(Sender:TObject;cid:TID;eid:TErrorID); virtual; stdcall;
    function GetCallerID:TID; virtual; stdcall;
    function GetActionID:TActionID; virtual; stdcall;
    procedure SetActionID(act:TActionID); virtual; stdcall;
    function GetCallerAction:TActionID; virtual; stdcall;
    procedure RestoreLastAction; virtual; stdcall;
    function GetInterfacedObjectOwner:TObject; virtual; stdcall;
    function RequestPosition(var px,py:Double;posreq:TPositionRequest;targetID:TID):boolean; virtual; stdcall;
    function RequestMainMaxArr(var arr:TMinMaxXYArr; targetID:TID):boolean; virtual; stdcall;
    //-- --//
    property OwnerUpInt:IUpdater read FOwnerUpInt write FOwnerUpInt;
    property OwnerUpIntExists:BOOLEAN read FOwnerUpIntExists write FOwnerUpIntExists;
    property InterfacedOwner:TObject read FInterfacedOwner write FInterfacedOwner;
    property ID:TID read FID write FID;
    property ActionID:TActionID read GetActionID write SetActionID;
  public
    constructor create(ACollection: TCollection); override;
    destructor destroy; override;
    property Updater:IUpdater read GetInterf;
    property InterfacedObjectOwner:TObject read GetInterfacedObjectOwner;
  published
  end;
Implementationsteil:

Delphi-Quellcode:
//----------------------------------------------------------------------------//
// TInterfacedCollectionItem = CLASS(TCollectionItem,IUpdater) //
//----------------------------------------------------------------------------//

//-[ CONSTRUCTOR / DESTUCTOR ]------------------------------------------------//

constructor TInterfacedCollectionItem.create(ACollection: TCollection);
begin
  inherited create(ACollection);
  SetInterfacedOwner(TObject(ACollection.Owner));
  FID := idNone;
  FActionID := aidNone;
end;

destructor TInterfacedCollectionItem.destroy;
begin
  FInterfacedOwner := NIL;
  FOwnerUpIntExists := no;
  FOwnerUpInt := NIL;
  inherited;
end;

//--[ PRIVATE ]---------------------------------------------------------------//

//--[ PROTECTED ]-------------------------------------------------------------//

//--[ Interface IInterface ]--------------------------------------------------//

function TInterfacedCollectionItem.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
begin
  if GetInterface(IID, Obj)
  then Result := S_OK
  else Result := E_NOINTERFACE;
end;

function TInterfacedCollectionItem._AddRef: Integer; stdcall;
begin
  Result := -1;
end;

function TInterfacedCollectionItem._Release: Integer; stdcall;
begin
  Result := -1;
end;

//--[ Interface IUpdater ]----------------------------------------------------//

procedure TInterfacedCollectionItem.SetInterfacedOwner(AOwner:TObject); stdcall;
begin
  FInterfacedOwner := NIL;
  FOwnerUpIntExists := no;
  FOwnerUpInt := NIL;
  if (AOwner<>NIL)
  then if AOwner.GetInterface(IUpdater,FOwnerUpInt)
  then begin
    FInterfacedOwner := AOwner;
    FOwnerUpIntExists := yes;
  end;
end;

function TInterfacedCollectionItem.GetInterf:IUpdater;
begin
  // Can be done this way, cause "I" know "I" have the Interface !!!
  Self.GetInterface(IUpdater,result);
end;

procedure TInterfacedCollectionItem.Call(Sender:TObject); stdcall;
begin
end;

procedure TInterfacedCollectionItem.CallOwner; stdcall;
begin
  if FOwnerUpIntExists THEN FOwnerUpInt.Call(Self);
end;

procedure TInterfacedCollectionItem.RaiseError(Sender:TObject;cid:TID;eid:TErrorID); stdcall;
begin
End;

function TInterfacedCollectionItem.GetCallerID:TID; stdcall;
begin
  Result := FID;
end;

function TInterfacedCollectionItem.GetActionID:TActionID; stdcall;
begin
  result := FActionID;
end;

procedure TInterfacedCollectionItem.SetActionID(act:TActionID); stdcall;
begin
  FActionID := act;
  FActionRead := no;
end;

function TInterfacedCollectionItem.GetCallerAction:TActionID; stdcall;
begin
  // Can be read only once if not RestoreLastAction !!!!
  result := aidNone;
  if not(FActionRead) then result := FActionID;
  FActionRead := yes;
end;

procedure TInterfacedCollectionItem.RestoreLastAction;
begin
  FActionRead := no;
end;

function TInterfacedCollectionItem.GetInterfacedObjectOwner:TObject; stdcall;
begin
  if Assigned(FInterfacedOwner) then Result:=FInterfacedOwner else Result := nil;
end;

function TInterfacedCollectionItem.RequestPosition(var px,py:Double;posreq:TPositionRequest;targetID:TID):boolean; stdcall;
begin
  result := no;
  px := 0;
  py := 0;
end;

function TInterfacedCollectionItem.RequestMainMaxArr(var arr:TMinMaxXYArr; targetID:TID):boolean; stdcall;
begin
  result := no;
end;

//--[ PUBLIC ]----------------------------------------------------------------//

//--[ PUBLISHED ]-------------------------------------------------------------//

////[ TInterfacedCollectionItem ]///////////////////////////////////////////////
Ihr muesst euch da jetzt nicht im Detail durchwurschteln.
Aber BIITE die GUID (SHIFT+CTRL+G) einfügen und hinter jede Methode stdcall;.
Die virtual; deklaration in der Basisklasse inst nicht notwendig, da hier die Methoden schon
explizit implementiert sind. Stört aber nicht und dient nur zur Sicherheit (gegen meinen Alzheimer).

- Die Standard-Aufrufkonvention für Schnittstellen ist register. Schnittstellen, die man von
verschiedenen Modulen gemeinsam benutzt, sollten die Methoden mit stdcall deklarieren.
Dies gilt insbesondere, wenn diese Module in verschiedenen Programmiersprachen erstellt wurden.

- Wenn Sie den Operator as oder QueryInterface() mit einer Schnittstelle einsetzen,
muss diese eine zugeordnete IID besitzen.

- In jedem Interface ist unterstellt, dass die Basisklasse oder ein Vorfahr die Methoden
von IUnknown zur Referenzzählung implementiert.

- Im Unterschied zu einer abstrakten Klasse enthält eine Schnittstelle überhaupt keine implementierte
Methode, alle Methoden sind abstrakt. Abstrakte Klassen lassen sich verwenden, wenn bereits ein
bestimmtes Grundverhalten in den abgeleiteten Klassen vorhanden sein soll.

Mhh... Ich hab schon lang überlegt mal ein TUT über Interfaces zu basteln. Aber gerade fehlt mir die Zeit.

MFG

LoCrux
“C++ is an insult to the human brain.” [Niklaus Wirth]

2B OR NOT 2B (.. THAT IS FF)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz