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.

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
privatehides the details;publicis what the class offers.readandwritecan point to a field or to a method.- A setter validates before storing.
- A property without
writeis read-only and may be computed. strict privateblocks 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.