简体   繁体   中英

How to support class methods in interface definitions in Delphi

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

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.

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;

您可以在类定义(TMyClass)中定义类方法(Delphi中的类过程),但不能在接口 (IMyClass)中定义。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM