How to support class methods in interface definitions in Delphi

I created a class method in a class that implements an interface, but I cannot define it inside an interface.

IMyClass = interface procedure someproc(); class function myfunc() : TMyClass; // compiler doesn't like this! end; TMyClass = class( TInterfacedObject, IMyClass ) public procedure someproc(); class function myfunc() : TMyClass; end; 

I want myfunc() create and return an instance of TMyClass . For example:

 somefunc( TMyClass.myfunc(), ... ); 

creates an instance of TMyClass and passes it to somefunc .

I can define function myfunc() : TMyClass; in the IMyClass interface, but if I put a class in front of it, the compiler will give me an error. If I leave this, it will give me several other errors "E2291 There is no implementation of the xyz.myfunc interface method" It simply does not accept the same signature in the interface as in the class.

I thought I saw this work before (class methods defined in interfaces), but maybe not.

If this is not directly supported, how do you do it?

(I use Delphi XE5 if that matters.)

+7
oop interface delphi
source share
3 answers

Interfaces are not classes and do not support methods marked as class , they only support class methods that are implemented and call instances of objects.

What you are looking for is most likely to be implemented as a factory class instead of using an interface.

+5
source share

What you are trying to achieve is not possible because it violates the binary specifications of the Delphi interfaces.

Any interface method in Delphi hid the first parameter - a pointer to an instance. Instance methods have the same hidden parameter ( Self , the same instance pointer), and because of this, they are binary, compatible with interface methods.

On the other hand, the hidden parameter of the class method is a pointer to the vtable class, therefore the methods of the Delphi class are incompatible with the methods of the Delphi interface.

Hypothetically, you might think of the following (binary compatible) declarations:

 IMyClass = interface procedure someproc(); function myfunc(): TMyClass; end; TMyClass = class( TInterfacedObject, IMyClass ) public procedure someproc(); class function myfunc(Inst: TMyClass) : TMyClass; static; end; 

Here I use the static specifier to remove a hidden parameter (class pointer vtable) that we do not need, and add the instance pointer parameter explicitly; but the compiler supports this syntax because the above is essentially the same as the simpler

 IMyClass = interface procedure someproc(); function myfunc(): TMyClass; end; TMyClass = class( TInterfacedObject, IMyClass ) public procedure someproc(); function myfunc() : TMyClass; end; 
+2
source share

You can define a class method (class procedure in Delphi) in the class definition (TMyClass), but not in the interface (IMyClass).

0
source share

All Articles