Add setter to property in child class

I have two Delphi classes. The parent class declares the FSSN string field and maps the SSN property to accessories that directly read and write the field. In my child class, I want to reuse the SSN property to use the setter from the child class (to convert the SSN, if possible, before writing it to the field).

The SSN property will be set using the parent class method, but (if the instance is an instance of a child class), I want the calling child node to be called. However, when I run the code, I never enter the child setter, and the field seems to be set directly using the property declaration in the parent.

Can this be done?

(I understand that I can do this by introducing the setter procedure into the parent class and redefining it in the child, I would prefer not to violate the parent class, if possible).

Here is what I still have (in a completely simplified version, of course):

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
+5
source share
2 answers

No; it's impossible.

A child class can access the parent class, but the parent does not know about the child, and you have nothing in the parent class declared virtual that you can use polymorphism for routing.

VMT, dscendant, . , , . .

+5

, , , . , , . , , getter setter, parent, . .

:

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

  TMyPerson = class(TCustomPerson)
  private
    function GetSSN: string;
    procedure SetSSN(ASSN: String);
  public
    property SSN: String read GetSSN write SetSSN; // Redeclaring the property

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

  function TMyPerson.GetSSN: string;
  begin
    Result := inherited SSN;  //retrieving data from the parent
  end;

  procedure TMyPerson.SetSSN(ASSN: String);
  begin
      inherited SSN := ValidateSSN(ASSN);  //Setting data in the parent
  end;
0

All Articles