Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Polymorphie und Interfaces in Delphi (https://www.delphipraxis.net/180618-polymorphie-und-interfaces-delphi.html)

Neutral General 3. Jun 2014 09:54

Delphi-Version: XE4

Polymorphie und Interfaces in Delphi
 
Hallo,

Mir ist gerade etwas aufgefallen. Angenommen wir haben 2 Interfaces die voneinander erben

Delphi-Quellcode:
IBaseInterface = interface;
IExtendedInterface = interface(IBaseInterface);
und eine Klasse die IExtendedInterface implementiert:

Delphi-Quellcode:
TKlasse = class(TInterfacedObject, IExtendedInterface);

Nun gibt es folgende Methode:

Delphi-Quellcode:
procedure Irgendwas(Base: IBaseInterface);

und der Aufruf:

Delphi-Quellcode:
var obj: TKlasse;
begin
  // ...
  Irgendwas(obj); // Inkompatible Typen: 'IBaseInterface' und 'TKlasse'
end;
Hab ich was verpasst oder sollte das nicht prinzipiell funktionieren?
Wenn ich TKlasse explizit zusätzlich IBaseInterface implementieren lasse (was ja eigentlich unnötig ist) dann funktionierts.

Hat das einen Grund (bin ich blöd?) oder ist Delphi blöd?

Der schöne Günther 3. Jun 2014 09:58

AW: Polymorphie und Interfaces in Delphi
 
Hatten wir kürzlich schon mal (suche gleich den Link): Ja, es ist eigentlich unnötig. Aber du musst das Parent-Interface trotzdem in der Typdefinition angeben. Sonst merkst du noch nichtmal zur Laufzeit mit Supports(..) dass es eigentlich IBaseInterface kann! :shock:
Delphi-Style. Gefällt mir auch nicht.

Update: http://www.delphipraxis.net/153524-i...ml#post1236634

himitsu 3. Jun 2014 10:01

AW: Polymorphie und Interfaces in Delphi
 
TKlasse implementiert nur IExtendedInterface.
Auf die Methoden von IBaseInterface kann man also nur über das IExtendedInterface zugreifen.

Soll die Klasse beide Interfaces implementieren, dann mußt du auch Beide angeben.
Delphi-Quellcode:
TKlasse = class(TInterfacedObject, IBaseInterface, IExtendedInterface);

Nur die angegebenen Interfaces (deren GUID) werden in die Interface-Liste der Klasse eingetragen und nur diese lassen sich "supporten", außer man erweitert die Support-Routine und macht es manuell.

[edit] :schnarsch:

alda 3. Jun 2014 10:04

AW: Polymorphie und Interfaces in Delphi
 
Ja da ist Delphi etwas eigen, aber der Grund für dieses Verhalten würde mich auch interessieren.

Alle Interfaces die eine Klasse unterstützen soll (für das Casten zur Laufzeit), müssen explizit von dieser Klasse implementiert werden, bei voneinander abgeleiteten Interfaces auch die Super-Interfaces wie Du gemerkt hast. Ausnahme wäre, dass eine Superklasse diese bereits implementiert, dann musst Du die Interfaces in deiner abgeleiteten Klasse nicht noch einmal explizit mit in die Klassendeklaration nehmen.

@himitsu:
Aber eine Klasse die IExtendedInterface implementiert, implementiert doch auch implizit IBaseInterface. In welcher Hinsicht macht das "Sinn", dass man nicht nach IBaseInterface casten kann, ohne dieses Interface zusätzlich noch mit in die Deklaration aufzunehmen.

himitsu 3. Jun 2014 10:11

AW: Polymorphie und Interfaces in Delphi
 
Den Grund hab ich in meinem letzten Post nacheditiert.

alda 3. Jun 2014 10:28

AW: Polymorphie und Interfaces in Delphi
 
Ok, also ist dieses Verhalten der TGUID Verwendung "geschuldet". Dennoch hätte ich erwartet, dass Embacadero es schafft einfach die GUIDs aller Super-Interfaces mit einzutragen ... andererseits ... :>

himitsu 3. Jun 2014 10:40

AW: Polymorphie und Interfaces in Delphi
 
Das wäre aber auch nicht so gut, wenn Delphi das einfach so machen würde, denn es kann ja gewollt sein, daß IBaseInterface nicht supported wird und was macht man dann?

Das mit den GUIDs liegt an Windows und nicht an Delphi. :zwinker:
Nur die GUID ist wichtig und den Namen interessiert keinen.
Du kannst das Interface problemlos umbenennen, bzw. jedes Programm/DLL kann einen anderen Namen vor dem Compilieren verwenden, solange die GUID und die ordinalen Positionen der beliebig benennbaren Methoden gleich bleibt.

alda 3. Jun 2014 11:20

AW: Polymorphie und Interfaces in Delphi
 
Zitat:

Das wäre aber auch nicht so gut, wenn Delphi das einfach so machen würde, denn es kann ja gewollt sein, daß IBaseInterface nicht supported wird und was macht man dann?
Genau darauf will ich ja hinaus: Gibt es diesen Fall? Ich hätte gesagt nein, da ich über das IExtendedInterface auch das IBaseInterface implementiere.

Uwe Raabe 3. Jun 2014 13:03

AW: Polymorphie und Interfaces in Delphi
 
Zitat:

Zitat von alda (Beitrag 1261194)
Zitat:

Das wäre aber auch nicht so gut, wenn Delphi das einfach so machen würde, denn es kann ja gewollt sein, daß IBaseInterface nicht supported wird und was macht man dann?
Genau darauf will ich ja hinaus: Gibt es diesen Fall? Ich hätte gesagt nein, da ich über das IExtendedInterface auch das IBaseInterface implementiere.

Diesen Fall wird es spätestens in dem Moment geben, wo Delphi das nicht mehr unterstützen würde. Die Tatsache, daß wir uns vielleicht im Moment keinen derartigen Fall vorstellen können, ist allenfall ein Zeichen unseres beschränkten Denkens und kein Beweis, daß es ihn nicht gibt oder geben wird.

Mikkey 3. Jun 2014 13:35

AW: Polymorphie und Interfaces in Delphi
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1261201)
Zitat:

Zitat von alda (Beitrag 1261194)
Zitat:

Das wäre aber auch nicht so gut, wenn Delphi das einfach so machen würde, denn es kann ja gewollt sein, daß IBaseInterface nicht supported wird und was macht man dann?
Genau darauf will ich ja hinaus: Gibt es diesen Fall? Ich hätte gesagt nein, da ich über das IExtendedInterface auch das IBaseInterface implementiere.

Diesen Fall wird es spätestens in dem Moment geben, wo Delphi das nicht mehr unterstützen würde. Die Tatsache, daß wir uns vielleicht im Moment keinen derartigen Fall vorstellen können, ist allenfall ein Zeichen unseres beschränkten Denkens und kein Beweis, daß es ihn nicht gibt oder geben wird.

Tut mir leid, wenn ich da widerspreche, aber wenn ein Objekt das Interface IExtendedInterface anbietet muss es per Definition auch IBaseInterface anbieten.

Wenn ich eine Klasse definiere, die IExtendedInterface implementiert, bekomme ich schließlich auch einen Compilerfehler, wenn sie nicht die Methoden von IBaseInterface implementiert.

Wenn ich den obigen Code leicht modifiziere, wird er vom Compiler anstandslos geschluckt:

Delphi-Quellcode:
var obj: TKlasse;
begin
  // ...
  Irgendwas(IExtendedInterface(obj));
end;
Es fehlt also schlicht und einfach der implizite Cast von Objektreferenz auf das implementierte Interface.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:46 Uhr.
Seite 1 von 3  1 23      

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