[fpc-pascal] Interfaces via implements keyword

Andrew Hall andrew.hall at shaw.ca
Thu Nov 26 03:48:05 CET 2009

As you probably guess, the issue for the last line " I2:=I1 as IIntf2;" is that I1 is implemented by "O: TClass1" which no longer supports"IIntf2" - hence the error "interface not supported".
It would be nice if the class could know it is part of an "implements" structure and defer to the "parent" class - but by their very nature interfaces abstract the implementation so there is no way for the classes to know each other implicitly.  However - there are several ways that you can achieve this - two suggestions are (the first is simple and likely achieves what you need with no work):

1) Always reference your host class through an interface you know will be implemented by the host class, therefore calling "as" from this interface will always find any of the interfaces your class may support.  The easiest would be to declare "I1: IUnknown" in the code below - I haven't tried it but that should work.

2) Store the host class reference in the other classes that implement the host and provide an "Owner: IUnknown" property in your "child" implementing classes to allow you to cast to any interface supported by the host class: "I2 := I1.Owner as IIntf2"

PS - normally your host class would not support the interface you are using "implements" to achieve... therefore the confusing circumstances of your first example would not normally happen - you'd be more likely to see this second example which is a little easier to decipher...


Andrew Hall.

On 25 Nov 09, at 11:59 , Denis Golovan wrote:

> Thanks for info.
> Well. Now I see the technical reason for it. 
> I thought so too.
> See example below. The same commenting again gives another results.
> The last Print call just says that interface is not supported (btw, in Delphi also) if implemented using "implements". 
> var C2:TClass2;
>     I1:IIntf1;
>     I2:IIntf2;
> begin
>   try
>     C2:=TClass2.Create;
>     C2.Print;
>     I1:=C2 as IIntf1;
>     I2:=C2 as IIntf2;
>     I2.Print;
>     I2:=I1 as IIntf2;
>     I2.Print;
>   except
>     on E:Exception do
>       WriteLn(E.Message);
>   end;
>   readln;
> end.

More information about the fpc-pascal mailing list