如何在Delphi中重写类属性getter

如何在Delphi中重写类属性getter,delphi,delphi-xe2,Delphi,Delphi Xe2,我定义了一个基类和一些派生类,它们永远不会被实例化。它们只包含类函数和两个类属性 问题是Delphi要求类属性的property get方法使用static关键字en声明,因此不能声明virtual,因此我可以在派生类中重写它 因此,此代码将导致编译错误: TQuantity = class(TObject) protected class function GetID: string; virtual; //Error: [DCC Error] E2355 Clas

我定义了一个基类和一些派生类,它们永远不会被实例化。它们只包含类函数和两个类属性

问题是Delphi要求类属性的property get方法使用static关键字en声明,因此不能声明virtual,因此我可以在派生类中重写它

因此,此代码将导致编译错误:

    TQuantity = class(TObject)
    protected
      class function GetID: string; virtual; //Error: [DCC Error] E2355 Class property accessor must be a class field or class static method
      class function GetName: string; virtual;
    public
      class property ID: string read GetID;
      class property Name: string read GetName;
    end;

    TQuantitySpeed = class(TQuantity)
    protected
      class function GetID: string; override;
      class function GetName: string; override;
    end;
所以问题是:如何定义其结果值可以在派生类中重写的类属性

使用DelphiXe2,更新4

更新: 根据David Heffernan的建议,用函数代替属性解决了这个问题:

    TQuantity = class(TObject)
    public
      class function ID: string; virtual;
      class function Name: string; virtual;
    end;

    TQuantitySpeed = class(TQuantity)
    protected
      class function ID: string; override;
      class function Name: string; override;
    end;
如何定义其结果值可以在派生类中重写的类属性

编译器错误消息表明,您不能:

E2355类属性访问器必须是类字段或类静态方法

类字段在通过继承相关的两个类之间共享。所以这不能用于多态性。类静态方法也不能提供多态行为


使用虚拟类函数而不是类属性。

所以我应该创建另一个虚拟类函数,并从类属性get方法调用它?@Bascy是的,这将是最简单的解决方案。@DavidHeffernan我没有正确阅读您的解决方案,我现在明白了,只是定义了一个公共类方法ID:string;事实上的类静态方法可以调用虚拟类方法,但不会获得多态行为,因为它是静态的。所以我能看到的唯一解决方案是一个普通类虚函数,而不是一个属性。哦,我明白了。静态类方法根本没有对类的引用(Self)——正如你所说的,我只是不明白。看起来真是太遗憾了!如果
ID
Name
是每个类的常量(getter方法只返回每个类的常量值),您可以使用
属性
并使用它们标记类。这对我来说是一个新概念。。。开始阅读它,但是检索值似乎比仅仅使用虚拟类方法要复杂一些。看来我错了。当我们没有类实例时,很难实现属性(我不知道如何实现:)。无论如何,请看一看如何使用属性来为类添加注释,例如,
[ID('my class ID')]
[Name('my class Name string')]
,然后在运行时提取这些类(对象)的属性值
type
  // Abstraction is used at sample to omit implementation
  TQuantity = class abstract
  protected
    class function GetID: string; virtual; abstract;
    class procedure SetID(const Value: string); virtual; abstract;
  public
    // Delphi compiler understands class getters and setters
    {class} property ID: string read GetID write SetID;
  end;

var
  Quantity: TQuantity;

begin
  Quantity.ID := '?';