Larry Lustig
Larry Lustig

Reputation: 51008

Add setter to property in descendant class

I have two Delphi classes. The parent class declares a string field FSSN and matching property SSN with accessors that read and write the field directly. In my child class I want to redeclare the property SSN to use a setter from the child class (to transform the SSN if possible before writing it to the field).

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

Can this be done?

(I realize I could accomplish this by introducing the setter procedure in the parent class and overriding in the child; I'd rather not disturb the parent class if possible).

Here's what I have so far (in a drastically 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

Upvotes: 5

Views: 855

Answers (2)

Red Romanov
Red Romanov

Reputation: 474

I have a workaround using RTTI. You just have to publish the SSN property.

 procedure TCustomPerson.LoadFromXML(ANode: IXMLNode);
 var ThisSSN: String;
 begin
    //extract SSN from XML into ThisSSN
    SetStrProp(Self,'SSN',ThisSSN);
 end

Upvotes: 0

Ken White
Ken White

Reputation: 125757

No; that's not possible.

The child class can access the parent class, but the parent has no knowledge of the child, and you don't have anything in the parent class declared as virtual that you can use polymorphism to route.

In the case of an overridden method, there's a VMT that can be used to route to the proper dscendant class, but a straight property assignment without a setter can't be virtualized. You need a setter in the parent that is declared as virtual, and then an override setter on the descendant will work. There's no way to virtualize a straight variable assignment.

Upvotes: 5

Related Questions