Hallo Maximov,
wie Hagen bereits dargestellt hat, handelt es sich bei Schnittstellen (Interfaces) um unterschiedliche "Sichten" auf ein und dasselbe Objekt. Weil die Identität eines Objekts jedoch ein Wesensmerkmal darstellt, scheint es tatsächlich überaschend, dass der von Dir diskutierte Code bei einen Vergleich der Art
Delphi-Quellcode:
myObj := TMyClass.Create;
myRefToInterfaceA := myObj;
myRefToInterfaceBA := myObj;
Result := Pointer(myRefToInterfaceA) = Pointer(myRefToInterfaceB);
den Wert
False zurückgibt.
Tatsächlich ist dies lediglich spezifisch für Wahl der Implementierung von Interfaces im
COM-Umfeld, bei der jede Klasse für jedes implementierte Interface seine eigene "Methodentabelle" bereitstellt, auf die (indirekt) durch die Referenz auf ein Interface verwiesen wird.
Obgleich es möglich ist, Schnittstellen voneinander erben zu lassen und Zuweisungen der Art
Delphi-Quellcode:
type
IMyInterface =
interface
['
{A GUID}']
end;
IMyInterfaceDescendant =
interface(IMyInterface)
['
{Another GUID}']
end;
TMyClass =
class(TInterfacedObject, IMyInterfaceDescendant)
end;
var
myObject: TMyClass;
myRefToInterface: IMyInterface;
myRefToInterfaceDescendant: IMyInterfaceDescendant;
begin
myObject := TMyClass.Create;
myRefToInterfaceDescendant := myObject;
myRefToInterface := myRefToInterfaceDescendant;
durchzuführen, obwohl die Klasse
TMyClass aus dem Beispiel das Interface
IMyInterface selbst nicht implementiert, ist eine Zuweisung der Art
myRefToInterface := myObject
nicht zulässig wie auch der Cast
myObject as IMyInterface
zu einer
Exception führt: Das Interface
IMyInterface wird von
TMyClass nicht implementiert, es kann keine Referenz auf die "Methodentabelle" zurückgegeben werden.
Was Du also machen kannst, wenn Du ohne "Identitätsinterface", wie Hagen es vorschlägt, an die Identität der Objekte zweier unterschiedlicher Interfaces herankommen möchtest, ist der Cast auf auf ein gemeinsames Interface, z.B.
IInterface, und der anschließende Vergleich der Art
Result := (myRefToAnInterface as IInterface) = (myRefToAnotherInterface as IInterface)
Achtung: Wie oben beschrieben sind Zuweisungen zu Vorfahren-Interfaces gültig, also im Speziellen Zuweisungen zum Wurzelinterface
IInterface. Ein Vergleich nach
Delphi-Quellcode:
var
myHelper1: IInterface;
myHelper2: IInterface;
begin
myHelper1 := ARefToAnInterface;
myHelper2 := ARefToAnnotherInterface;
Result := myHelper1 = myHelper2;
kann demnach zu fehlern führen!