![]() |
Delphi-Version: XE4
Polymorphie und Interfaces in Delphi
Hallo,
Mir ist gerade etwas aufgefallen. Angenommen wir haben 2 Interfaces die voneinander erben
Delphi-Quellcode:
und eine Klasse die IExtendedInterface implementiert:
IBaseInterface = interface;
IExtendedInterface = interface(IBaseInterface);
Delphi-Quellcode:
TKlasse = class(TInterfacedObject, IExtendedInterface);
Nun gibt es folgende Methode:
Delphi-Quellcode:
procedure Irgendwas(Base: IBaseInterface);
und der Aufruf:
Delphi-Quellcode:
Hab ich was verpasst oder sollte das nicht prinzipiell funktionieren?
var obj: TKlasse;
begin // ... Irgendwas(obj); // Inkompatible Typen: 'IBaseInterface' und 'TKlasse' end; 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? |
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: ![]() |
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: |
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. |
AW: Polymorphie und Interfaces in Delphi
Den Grund hab ich in meinem letzten Post nacheditiert.
|
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 ... :>
|
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. |
AW: Polymorphie und Interfaces in Delphi
Zitat:
|
AW: Polymorphie und Interfaces in Delphi
Zitat:
|
AW: Polymorphie und Interfaces in Delphi
Zitat:
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:
Es fehlt also schlicht und einfach der implizite Cast von Objektreferenz auf das implementierte Interface.
var obj: TKlasse;
begin // ... Irgendwas(IExtendedInterface(obj)); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:51 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