6.7.7 Overriding properties

Properties can be overridden in descendent classes, just like methods. The difference is that for properties, the overriding can always be done: properties should not be marked “virtual” so they can be overridden, they are always overridable (in this sense, properties are always “virtual”). The type of the overridden property does not have to be the same as the parents class property type.

Since they can be overridden, the keyword “inherited” can also be used to refer to the parent definition of the property. For example consider the following code:

type  
  TAncestor = class  
  private  
    FP1 : Integer;  
  public  
    property P: integer Read FP1 write FP1;  
  end;  
 
  TClassA = class(TAncestor)  
  private  
    procedure SetP(const AValue: char);  
    function getP : Char;  
  public  
    constructor Create;  
    property P: char Read GetP write SetP;  
  end;  
 
procedure TClassA.SetP(const AValue: char);  
 
begin  
  Inherited P:=Ord(AValue);  
end;  
 
procedure TClassA.GetP : char;  
 
begin  
  Result:=Char((Inherited P) and $FF);  
end;

TClassA redefines P as a character property instead of an integer property, but uses the parents P property to store the value.

Care must be taken when using virtual get/set routines for a property: setting the inherited property still observes the normal rules of inheritance for methods. Consider the following example:

type  
  TAncestor = class  
  private  
    procedure SetP1(const AValue: integer); virtual;  
  public  
    property P: integer write SetP1;  
  end;  
 
  TClassA = class(TAncestor)  
  private  
    procedure SetP1(const AValue: integer); override;  
    procedure SetP2(const AValue: char);  
  public  
    constructor Create;  
    property P: char write SetP2;  
  end;  
 
constructor TClassA.Create;  
begin  
  inherited P:=3;  
end;

In this case, when setting the inherited property P, the implementation TClassA.SetP1 will be called, because the SetP1 method is overridden.

If the parent class implementation of SetP1 must be called, then this must be called explicitly:

constructor TClassA.Create;  
begin  
  inherited SetP1(3);  
end;