Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

[Beispiel] Wie funktionieren Interfaces?

  Alt 3. Feb 2016, 16:40
Im Anhang findet man unterschiedliche Arten die Interfaces
Delphi-Quellcode:
unit PlayWithInterfaces.Intf;

interface

type
  IFoo = interface
    [ '{39D32762-2113-4315-A06E-909B2F5D0832}' ]
    function GetFooInfo( ): string;
  end;

  IBar = interface
    [ '{F9F9977D-A03D-49A4-B8A9-ED3566C8D8C9}' ]
    function GetBarInfo( ): string;
  end;

  IFooBar = interface
    [ '{6ABC365F-94D5-461E-BB2C-406837E8287D}' ]
    function GetBar: IBar;
    property Bar: IBar read GetBar;
    function GetFoo: IFoo;
    property Foo: IFoo read GetFoo;
  end;

implementation

end.
zu implementieren.

Mit dem Konsolen-Programm
Delphi-Quellcode:
program PlayWithInterfaces;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.StrUtils,
  System.SysUtils,
  PlayWithInterfaces.Intf in 'PlayWithInterfaces.Intf.pas',
  PlayWithInterfaces.Impl.Basic in 'PlayWithInterfaces.Impl.Basic.pas',
  PlayWithInterfaces.Impl.Split in 'PlayWithInterfaces.Impl.Split.pas',
  PlayWithInterfaces.Impl.Aggregated in 'PlayWithInterfaces.Impl.Aggregated.pas',
  PlayWithInterfaces.Impl.Contained in 'PlayWithInterfaces.Impl.Contained.pas',
  PlayWithInterfaces.Impl.Routed in 'PlayWithInterfaces.Impl.Routed.pas',
  PlayWithInterfaces.Impl.Attached in 'PlayWithInterfaces.Impl.Attached.pas';

procedure WorkWithBar( Bar: IBar; const Info: string );
begin
  Writeln( 'Bar - ', Info );
  Writeln( 'Bar.GetBarInfo = ', Bar.GetBarInfo );

  Writeln( 'Bar ', IfThen( Supports( Bar, IFoo ), '', 'NOT ' ), 'supports IFoo' );
  Writeln( 'Bar ', IfThen( Supports( Bar, IFooBar ), '', 'NOT ' ), 'supports IFooBar' );
  Writeln;
end;

procedure WorkWithFoo( Foo: IFoo; const Info: string );
begin
  Writeln( 'Foo - ', Info );
  Writeln( 'Foo.GetFooInfo = ', Foo.GetFooInfo );

  Writeln( 'Foo ', IfThen( Supports( Foo, IBar ), '', 'NOT ' ), 'supports IBar' );
  Writeln( 'Foo ', IfThen( Supports( Foo, IFooBar ), '', 'NOT ' ), 'supports IFooBar' );
  Writeln;
end;

procedure WorkWithFooBar( FooBar: IFooBar; const Info: string );
begin
  Writeln( 'FooBar - ', Info );
  Writeln;

  WorkWithBar( FooBar.Bar, 'FooBar.Bar' );
  WorkWithFoo( FooBar.Foo, 'FooBar.Foo' );

  Writeln( 'FooBar ', IfThen( Supports( FooBar, IBar ), '', 'NOT ' ), 'supports IBar' );
  Writeln( 'FooBar ', IfThen( Supports( FooBar, IFoo ), '', 'NOT ' ), 'supports IFoo' );
  Writeln;
end;

procedure Main;
var
  lAttached: TAttachedFooBar;
begin
  WorkWithFooBar( TBasicFooBar.Create, TBasicFooBar.ClassName );
  WorkWithFooBar( TSplitFooBar.Create, TSplitFooBar.ClassName );
  WorkWithFooBar( TAggregatedFooBar.Create, TAggregatedFooBar.ClassName );
  WorkWithFooBar( TContainedFooBar.Create, TContainedFooBar.ClassName );
  WorkWithFooBar( TRoutedFooBar.Create, TRoutedFooBar.ClassName );

  lAttached := TAttachedFooBar.Create;
  try
    WorkWithFooBar( lAttached, lAttached.ClassName );
  finally
    lAttached.Free;
  end;
end;

begin
  ReportMemoryLeaksOnShutdown := True;
  try
    Main;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
kann man dann sehen, welche Unterschiede in den einzelnen Implementierungen bestehen und welche Klasse konkret die Information liefert.

IFoo.GetFooInfo und IBar.GetBarInfo liefern den Klassen-Namen und den Methoden-Namen zurück:
Code:
FooBar - TBasicFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TBasicFooBar.GetBarInfo
Bar supports IFoo
Bar supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TBasicFooBar.GetFooInfo
Foo supports IBar
Foo supports IFooBar

FooBar supports IBar
FooBar supports IFoo

FooBar - TSplitFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TSplitBar.GetBarInfo
Bar NOT supports IFoo
Bar NOT supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TSplitFoo.GetFooInfo
Foo NOT supports IBar
Foo NOT supports IFooBar

FooBar NOT supports IBar
FooBar NOT supports IFoo

FooBar - TAggregatedFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TAggregatedBar.GetFooInfo
Bar NOT supports IFoo
Bar supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TAggregatedFoo.GetFooInfo
Foo NOT supports IBar
Foo supports IFooBar

FooBar NOT supports IBar
FooBar NOT supports IFoo

FooBar - TContainedFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TContainedBar.GetFooInfo
Bar NOT supports IFoo
Bar NOT supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TContainedFoo.GetFooInfo
Foo NOT supports IBar
Foo NOT supports IFooBar

FooBar NOT supports IBar
FooBar NOT supports IFoo

FooBar - TRoutedFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TRoutedBar.GetFooInfo
Bar supports IFoo
Bar supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TRoutedFoo.GetFooInfo
Foo supports IBar
Foo supports IFooBar

FooBar supports IBar
FooBar supports IFoo

FooBar - TAttachedFooBar

Bar - FooBar.Bar
Bar.GetBarInfo = TAttachedFooBarImplementer.GetBarInfo
Bar supports IFoo
Bar supports IFooBar

Foo - FooBar.Foo
Foo.GetFooInfo = TAttachedFooBarImplementer.GetFooInfo
Foo supports IBar
Foo supports IFooBar

FooBar supports IBar
FooBar supports IFoo
P.S. Von den ganz schrägen Implementierungen habe ich jetzt mal Abstand genommen.
Angehängte Dateien
Dateityp: zip PlayWithInterfaces.zip (4,5 KB, 51x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat