5

我有两个 Delphi 课程。父类声明一个字符串字段 FSSN 和匹配的属性 SSN,访问器直接读取和写入该字段。在我的子类中,我想重新声明属性 SSN 以使用子类中的设置器(如果可能,在将 SSN 写入字段之前对其进行转换)。

属性 SSN 将由父类的方法设置,但是(如果实例是子类的实例)我希望调用设置器。但是,当我运行代码时,我从不输入子设置器,并且该字段似乎是直接使用父级中的属性声明设置的。

这可以做到吗?

(我意识到我可以通过在父类中引入 setter 过程并在子类中覆盖来实现这一点;如果可能的话,我宁愿不打扰父类)。

到目前为止,这是我所拥有的(当然,在一个大大简化的版本中):

TCustomPerson = class(TObject)
  protected
    FSSN: String;
  public
    procedure LoadFromXML(ANode: IXMLNode);
    property SSN: String read FSSN write FSSN;

TMyPerson = class(TCustomPerson)
  protected
    procedure SetSSN(ASSN: String);
  public
    property SSN: String read FSSN write SetSSN; // <=== Setter introduced.

 procedure TCustomPerson.LoadFromXML(ANode: IXMLNode);
 var ThisSSN: String;
 begin
    //extract SSN from XML into ThisSSN
    SSN := ThisSSN;                             // Expect to invoke SetSSN.
 end

procedure TMyPerson.SetSSN(ASSN: String);
begin
    FSSN := ValidateSSN(ASSN);                  // <== Breakpoint here never reached.
end
4

2 回答 2

5

不; 那是不可能的。

子类可以访问父类,但是父类不知道子类,并且父类中没有任何可以使用多态性进行路由的声明为虚拟的东西。

在重写方法的情况下,有一个 VMT 可用于路由到正确的子类,但无法虚拟化没有设置器的直接属性分配。您需要在父级中声明为虚拟的设置器,然后后代上的覆盖设置器将起作用。没有办法虚拟化直接的变量赋值。

于 2012-09-29T21:17:20.207 回答
0

我有一个使用 RTTI 的解决方法。您只需发布 SSN 属性。

 procedure TCustomPerson.LoadFromXML(ANode: IXMLNode);
 var ThisSSN: String;
 begin
    //extract SSN from XML into ThisSSN
    SetStrProp(Self,'SSN',ThisSSN);
 end
于 2019-03-13T03:04:12.100 回答