10
votes

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.)

3
Implement the interface method with an instance method rather than a class methodDavid Heffernan
It works as an instance method, but it requires an instance rather than the class.David Schwartz
That's right. You need an instance to implement an interface.David Heffernan
I've been reading up on some Java 8 features, and they now include ways to define static members (Delphi class methods) within interfaces. I was wondering if there's any way to do it in Delphi.David Schwartz
Delphi interfaces are COM interfaces and bound by the implementation details of COMDavid Heffernan

3 Answers

6
votes

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.

2
votes

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;
0
votes

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