DMarlon Studio

Lesson 2 · 2 of 20

Visibility and properties · Pascal

Protect your class data with private and public, and expose it through properties that validate on write and compute on read in Object Pascal.

Pascal · Visibility and properties in DMarlon Studio: the example's code and its output in the terminal

Visibility sections say who may touch each member. Whatever sits under `private` (the FPrice field and the SetPrice and GetPriceWithVat methods) is the class's own business; whatever sits under `public` is its visible face. The F prefix for fields and Get/Set for their methods are Pascal conventions.

A property looks like a field but decides what happens on read and on write. property Price: Double read FPrice write SetPrice reads the field directly and, on write, calls the method. So lamp.Price := 34.90 really runs SetPrice(34.90), which only accepts prices that are not negative.

The output proves it: after lamp.Price := -5, the price is still 34.90. Nothing outside the class can bypass the rule, because the field is private and the property is the only way to change it.

PriceWithVat has only read, which makes it read-only, and it stores nothing: GetPriceWithVat works out the price with 21 % VAT every time it is read. Name, on the other hand, is a plain public field.

One Free Pascal detail: private protects members from other units, but code in the same unit (here, the program itself) could still reach FPrice. For a full wall, use `strict private`. Lazarus components work the same way: Caption and Width are properties with a setter behind them.

Code · main.pas

program main;type  TProduct = class  private    FPrice: Double;    procedure SetPrice(AValue: Double);    function GetPriceWithVat: Double;  public    Name: String;    property Price: Double read FPrice write SetPrice;    property PriceWithVat: Double read GetPriceWithVat;  // computed, read-only  end;procedure TProduct.SetPrice(AValue: Double);begin  if AValue >= 0 then FPrice := AValue;  // a negative price is ignoredend;function TProduct.GetPriceWithVat: Double;begin  Result := FPrice * 1.21;end;var lamp: TProduct;begin  lamp := TProduct.Create;  lamp.Name := 'Desk lamp';  lamp.Price := 34.90;  // calls SetPrice(34.90)  WriteLn(lamp.Name, ': ', lamp.Price:0:2, ' EUR, ', lamp.PriceWithVat:0:2, ' with VAT');  lamp.Price := -5;  WriteLn('After trying -5: ', lamp.Price:0:2, ' EUR');  lamp.Free;end.

Output · fpc main.pas && ./main

Desk lamp: 34.90 EUR, 42.23 with VAT
After trying -5: 34.90 EUR

Key points

  • private hides the details; public is what the class offers.
  • read and write can point to a field or to a method.
  • A setter validates before storing.
  • A property without write is read-only and may be computed.
  • strict private blocks access even from the same unit.

Exercise

Add a Stock: Integer property whose setter rejects negative values, and a read-only StockValue property that returns Price * Stock.