AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Polymorphie und Interfaces in Delphi

Ein Thema von Neutral General · begonnen am 3. Jun 2014 · letzter Beitrag vom 4. Jun 2014
Antwort Antwort
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#1

AW: Polymorphie und Interfaces in Delphi

  Alt 3. Jun 2014, 14:38
Ein Problem mit solchen impliziten Cast hat man, wenn die Klasse implizit mehrere Versionen des Basis-Interfaces hat.
Z.B. TKlasse = class(TObject, IExtendedInterface_1, IExtendedInterface_2). Welche Implementierung soll man nehmen? (Die
Implementierungen können unterschiedlich delegiert sein...)

Der Compiler könnte sich natürlich etwas mehr Mühe machen in eindeutigen Fällen ein passendes Interface zu suchen,
aber die mit impliziten Cast verbundene Raterei verursacht eigentlich immer an unerwarteter Stelle Probleme.
Dein Beispiel zieht nicht, weil die Delphi-Syntax keine zwei Implementierungen einer Funktion der Vorfahrenklasse erlaubt. Im folgenden Code habe ich das mal über zwei voneinander erbenden Klassen versucht, aber damit bekommt man auch nicht den Aufruf verschiedener Implementierungen hin:

Delphi-Quellcode:
unit IFTest;

interface

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

type
  IBase = interface(IInterface)
    function f1(): Integer;
  end;

  IExtend1 = interface(IBase)
    function f2(): Integer;
  end;

  IExtend2 = interface(IBase)
    function f3(): Integer;
  end;

  TK1 = class(TInterfacedObject, IExtend1)
    function f1(): Integer; virtual;
    function f2(): Integer;
  end;

  TK2 = class(TK1, IExtend2)
    function f1(): Integer; override;
    function f3(): Integer;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure testF(i: IBase);
begin
end;

function TK1.f1(): Integer;
begin
  result := 11;
end;

function TK1.f2(): Integer;
begin
  result := 12;
end;

function TK2.f1(): Integer;
begin
  result := 21;
end;

function TK2.f3(): Integer;
begin
  result := 23;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
  o1: TK1;
  o2: TK2;
  i1, i2, i3: Integer;
begin
  o1 := TK1.Create();
  o2 := TK2.Create();
  testF(IExtend1(o1));
  testF(IExtend2(o2));
  i1 := o1.f1();
  i2 := o2.f1();
  i3 := (TK1(o2)).f1();
  ShowMessage(Format('o1: %d, o2: %d, Base(o2): %d', [i1, i2, i3]));
  // Ausgabe: 11 / 21 / 21
end;

end.
Möglicherweise könnte das aber irgendwann mal klappen, insoweit könnte Uwe Raabes Einwand gerechtfertigt sein.

Edit:
Ziehe meinen Einwand zurück, mit "reintroduce" in der TK2-Definition (anstelle "virtual"/"override") wird tatsächlich 11/21/11 ausgegeben.

Geändert von Mikkey ( 3. Jun 2014 um 15:18 Uhr)
  Mit Zitat antworten Zitat
Patito

Registriert seit: 8. Sep 2006
108 Beiträge
 
#2

AW: Polymorphie und Interfaces in Delphi

  Alt 3. Jun 2014, 14:47
Dein Beispiel zieht nicht, weil die Delphi-Syntax keine zwei Implementierungen einer Funktion der Vorfahrenklasse erlaubt.
Schau Dir die Syntax zum implementieren und deligieren von Interfaces noch mal genau an....
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.199 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Polymorphie und Interfaces in Delphi

  Alt 3. Jun 2014, 15:04
Dein Beispiel zieht nicht, weil die Delphi-Syntax keine zwei Implementierungen einer Funktion der Vorfahrenklasse erlaubt.
Schau Dir die Syntax zum implementieren und deligieren von Interfaces noch mal genau an....

Wollte ich auch grade sagen. Stichwort "Method Resolution clause". Hier ein Beispiel:

Delphi-Quellcode:
program Project4;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
   IBaseInterface = interface
      procedure baseMethod();
   end;

   IChildInterface1 = interface(IBaseInterface)
      // Stub
   end;

   IChildInterface2 = interface(IBaseInterface)
      // Stub
   end;

   TMyObject1 = class(TInterfacedObject, IChildInterface1)
      public procedure baseMethod(); virtual; abstract;
   end;

   TMyObject2 = class(TMyObject1, IChildInterface1, IChildInterface2)
      procedure baseForChildInterface1();
      procedure baseForChildInterface2();

      procedure IChildInterface2.baseMethod = baseForChildInterface1;
      procedure IChildInterface1.baseMethod = baseForChildInterface2;
   end;

{ TMyObject2 }

procedure TMyObject2.baseForChildInterface1();
begin
   WriteLn('Das ist "baseForChildInterface1()"');
end;

procedure TMyObject2.baseForChildInterface2();
begin
   WriteLn('Das ist "baseForChildInterface2()"');
end;

var
   iChild1Reference: IChildInterface1;
   iChild2Reference: IChildInterface2;
   objRef: TMyObject2;

begin
   try

      objRef := TMyObject2.Create();

      iChild1Reference := objRef;
      iChild2Reference := objRef;

      iChild1Reference.baseMethod();
      iChild2Reference.baseMethod();

   except
      on E: Exception do
         WriteLn(E.ClassName, ': ', E.Message);
   end;

   readln;

end.
Ein realitätsnahes Beispiel hierfür will mir aber auch nicht einfallen.
  Mit Zitat antworten Zitat
alda

Registriert seit: 24. Mär 2014
Ort: Karlsruhe
93 Beiträge
 
Delphi XE6 Architect
 
#4

AW: Polymorphie und Interfaces in Delphi

  Alt 3. Jun 2014, 15:08
Zitat:
Ein Problem mit solchen impliziten Cast hat man, wenn die Klasse implizit mehrere Versionen des Basis-Interfaces hat.
Z.B. TKlasse = class(TObject, IExtendedInterface_1, IExtendedInterface_2). Welche Implementierung soll man nehmen? (Die
Implementierungen können unterschiedlich delegiert sein...)
Danke, der Gedankengang hatte mir gefehlt.
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#5

AW: Polymorphie und Interfaces in Delphi

  Alt 3. Jun 2014, 16:09
Dein Beispiel zieht nicht, weil die Delphi-Syntax keine zwei Implementierungen einer Funktion der Vorfahrenklasse erlaubt.
Schau Dir die Syntax zum implementieren und deligieren von Interfaces noch mal genau an....
Da spielt nur mein etwas älteres XE nicht mit, nur die Variante mit zwei voneinander abgeleiteten Klassen s.o. funktioniert.

Zitat:
Ein realitätsnahes Beispiel hierfür will mir aber auch nicht einfallen.
Mir auch nicht. Selbst wenn so etwas aus irgendeiner Notwendigkeit gemacht werden würde, hielte ich es für extrem schlechten Stil, wenn eine Methode gleichen Namens einer Objektinstanz verschiedene Dinge tut.

Geändert von Mikkey ( 3. Jun 2014 um 17:06 Uhr)
  Mit Zitat antworten Zitat
Patito

Registriert seit: 8. Sep 2006
108 Beiträge
 
#6

AW: Polymorphie und Interfaces in Delphi

  Alt 4. Jun 2014, 12:54
[...]
Ein realitätsnahes Beispiel hierfür will mir aber auch nicht einfallen.
Ein Beispiel wären z.B. Methoden zum Schreiben eines Logfiles im Basis-Interface:

Delphi-Quellcode:
IBase = interface(IInterface)
  procedure SetLogfile(const FileName: TFileName);
  procedure WriteLog(const LogInfo: String);
end;

IRead = interface(IBase);
IWrite = interface(IBase);
Die Interfaces zum Schreiben der Log-Infos sind in IRead und IWrite dieselben, aber Reader und Writer
könnten unterschiedliche Logfiles verwenden.

Dass man Interface-Methoden beliebig auf eigene Implementierungen mit anderem Namen umbiegen kann ist
ein recht zentrales Feature von Interfaces. Es löst die ganzen Probleme, die man in anderen Programmiersprachen
bei rein Klassen-basierter Mehrfachvererbung hat (C++).
Mehr oder weniger ist das mal ein Featur, bei dem man mal von einem echten Vorteil von Delphi sprechen könnte.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:49 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-2025 by Thomas Breitkreuz