Visibility & Properties
Members declared before any specifier are published if the class is compiled with {$M+} (or descends from TPersistent), otherwise public.
25.1 Visibility specifiers
the class and all code in the same unit strict private the class only the class, descendants, and code in the same unit strict protected the class and descendants only everyone + RTTI generated (Object Inspector, streaming to .lfm/.dfm) legacy COM automation (obsolete)
Members declared before any specifier are published if the class is compiled with {$M+} (or descends from TPersistent), otherwise public. Use strict private for real encapsulation.
25.2 Properties
A property looks like a field to callers but can map to a field or to getter/setter methods:
property Name: string read FName write FName; property Count: Integer read GetCount write SetCount; property Id: Integer read FId; Write-only (rare)
property Password: string write SetPassword; Indexed (shared accessor)
property Left: Integer index 0 read GetCoord write SetCoord;
property Items[Index: Integer]: string read GetItem write SetItem; default; Default value (streaming)
property Visible: Boolean read FVisible write FVisible default True;
property Caption: string read FCaption write FCaption stored IsCaptionStored;
class property Count: Integer read FCount;
type
TTemperature = class
private
FCelsius: Double;
function GetFahrenheit: Double;
function GetKelvin: Double;
procedure SetFahrenheit(AValue: Double);
procedure SetCelsius(AValue: Double);
public
property Celsius: Double read FCelsius write SetCelsius;
property Fahrenheit: Double read GetFahrenheit write SetFahrenheit;
property Kelvin: Double read GetKelvin; // read-only
end;
function TTemperature.GetKelvin: Double;
begin
Result := FCelsius + 273.15;
end;
procedure TTemperature.SetCelsius(AValue: Double);
begin
if AValue < -273.15 then
raise ERangeError.Create('Below absolute zero');
FCelsius := AValue;
end;
function TTemperature.GetFahrenheit: Double;
begin
Result := FCelsius * 9 / 5 + 32;
end;
procedure TTemperature.SetFahrenheit(AValue: Double);
begin
Celsius := (AValue - 32) * 5 / 9; // reuse validation
end;25.3 Array properties and default
type
TMatrix = class
private
FData: array of Double;
FRows, FCols: Integer;
function GetCell(R, C: Integer): Double;
procedure SetCell(R, C: Integer; AValue: Double);
public
constructor Create(ARows, ACols: Integer);
property Cells[R, C: Integer]: Double read GetCell write SetCell; default;
property Rows: Integer read FRows;
property Cols: Integer read FCols;
end;
constructor TMatrix.Create(ARows, ACols: Integer);
begin
inherited Create;
FRows := ARows;
FCols := ACols;
SetLength(FData, ARows * ACols);
end;
function TMatrix.GetCell(R, C: Integer): Double;
begin
Result := FData[R * FCols + C];
end;
procedure TMatrix.SetCell(R, C: Integer; AValue: Double);
begin
FData[R * FCols + C] := AValue;
end;
// usage: M[1, 2] := 3.5; — same as M.Cells[1, 2] := 3.525.4 Events are properties too
A form assigns a handler: Downloader.OnDone := @DownloadFinished; (objfpc) or Downloader.OnDone := DownloadFinished; (Delphi). This "method pointer" mechanism is the foundation of the LCL/VCL event model.
type
TNotifyEvent = procedure(Sender: TObject) of object; // already declared in Classes
TDownloader = class
private
FOnDone: TNotifyEvent;
public
procedure Run;
property OnDone: TNotifyEvent read FOnDone write FOnDone;
end;
procedure TDownloader.Run;
begin
// ... work ...
if Assigned(FOnDone) then
FOnDone(Self); // fire the event
end;