5

2つの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

いいえ; それは可能ではありません。

子クラスは親クラスにアクセスできますが、親には子の知識がなく、ポリモーフィズムを使用してルーティングできる仮想として宣言された親クラスには何もありません。

オーバーライドされたメソッドの場合、適切なdscendantクラスにルーティングするために使用できる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 に答える