Delphi:像Java一样构造抽象类

Delphi:像Java一样构造抽象类,java,delphi,abstract-class,Java,Delphi,Abstract Class,好奇的是,我能用类似于Delphi的Java风格构造一个抽象类吗 Java声明: public abstract class Foo { public abstract void test(); } 使用方法: public void testCsontruct() { Foo clsfoo = new Foo(){ public void test(){ //....do something here } }; } procedure testUs

好奇的是,我能用类似于Delphi的Java风格构造一个抽象类吗

Java声明:

public abstract class Foo {
  public abstract void test();
}
使用方法:

public void testCsontruct() {
  Foo clsfoo = new Foo(){
    public void test(){
      //....do something here

    }
  };
}
procedure testUse;
var
  foo:Tfoo;
begin
  foo:=Tfoo.Create; //can we implement the test method here ? how?
end;
德尔福宣言:

Tfoo = class
public
  procedure test; virtual; abstract;
end;
使用方法:

public void testCsontruct() {
  Foo clsfoo = new Foo(){
    public void test(){
      //....do something here

    }
  };
}
procedure testUse;
var
  foo:Tfoo;
begin
  foo:=Tfoo.Create; //can we implement the test method here ? how?
end;

Java功能是匿名类。它们在许多场景中都很有用。正如您所说明的,它们通常用于捕获封闭范围内的变量

Delphi中没有类似的语法。匿名方法很接近,但是没有语法允许您用匿名方法替换实例化对象的虚拟方法


您需要使用子类来提供虚拟方法的具体实现。您可以在编译时以通常的方式生成子类,也可以在运行时使用虚拟方法拦截器或类似的VMT技巧生成子类。

您可以使用虚拟方法拦截器实现这一点:

uses
  Rtti;
...
begin
  foo := TFoo.Create;
  vmi := TVirtualMethodInterceptor.Create(foo.ClassType);

  vmi.OnBefore :=
      procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray<TValue>; out DoInvoke: Boolean;
      out Result: TValue)
    begin
      if Method.Name = 'test' then
      begin
        DoInvoke := false;
        // do something here
      end;
    end;
  vmi.Proxify(foo);

  foo.test;

  foo.Free;
  vmi.Free;
end;
使用
Rtti;
...
开始
foo:=TFoo.Create;
vmi:=TVirtualMethodInterceptor.Create(foo.ClassType);
vmi.OnBefore:=
过程(实例:TObject;方法:TRttiMethod;常量Args:TArray;out-DoInvoke:Boolean;
输出结果:TValue)
开始
如果Method.Name='test',则
开始
DoInvoke:=假;
//在这里做点什么
结束;
结束;
供应商管理库存代理(foo);
foo.test;
foo.Free;
免费供应商管理库存;
结束;

不过,我更喜欢在子类中实际实现。

谢谢,这就是我的想法。谢谢分享。我更喜欢做子类,因为它更简单。实际上这是一种子类的形式。该类在运行时被修改。这是一种观点,认为VMT的内容是类定义的一部分,因此更改VMT就是更改类。@DavidHeffernan不仅仅是一种形式的子类,它是子类,因为TVirtualMethodInterceptor创建的类实际上继承了您传入的类(只需打印出类层次结构)。我已经搜索了一段时间,这是我找到的最近的: