Reputation: 1844
I created a class method in a class that implements an interface, but I can't seem to define it inside of the 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()
to create and return an instance of TMyClass
. For example:
somefunc( TMyClass.myfunc(), ... );
creates an instance of TMyClass
and passes it into somefunc
.
I can define function myfunc() : TMyClass;
in the IMyClass interface, but if I put class
in front of it, the compiler gives me an error. If I leave it off, it gives me several other errors "E2291 Missing implementation of interface method xyz.myfunc" It just doesn't accept the same signature in the interface as in the class.
I thought I've seen this work before (class methods defined in interfaces) but maybe not.
If this isn't supported directly, how do you do it?
(I'm using Delphi XE5, in case it matters.)
Upvotes: 14
Views: 6713
Reputation: 27493
What you are trying to achieve is impossible because it violates binary specifications of Delphi interfaces.
Any interface method in Delphi have hidden first parameter - pointer to an instance. Instance methods have the same hidden parameter (Self
, the same pointer to an instance) and because of this they are binary compatible with interface methods.
On the other hand the hidden parameter of a class method is a pointer to the class vtable, so Delphi class methods are binary incompartible with Delphi interface methods.
Hypothetically you could 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 static
specifier to remove the hidden parameter (class vtable pointer) we don't need and add the instance pointer parameter explicitely; but the compiler does support such syntax because the above is essentially the same as a simpler
IMyClass = interface
procedure someproc();
function myfunc(): TMyClass;
end;
TMyClass = class( TInterfacedObject, IMyClass )
public
procedure someproc();
function myfunc() : TMyClass;
end;
Upvotes: 4
Reputation: 4909
You can define a class method (class procedure in Delphi) in a class definition (TMyClass) but not in an interface (IMyClass ).
Upvotes: 0
Reputation: 598134
Interfaces are not classes and do not support methods marked as class
, they only support non-class
methods that are implemented and called on object instances.
What you are looking for will most likely have to be implemented as a class factory instead of using an interface.
Upvotes: 9