DMarlon Studio

Lección 2 · 2 de 20

Visibilidad y propiedades · Pascal

Proteja los datos de sus clases con private y public y expóngalos con propiedades que validan al escribir y calculan al leer en Object Pascal.

Pascal · Visibilidad y propiedades en DMarlon Studio: el código del ejemplo y su salida en la terminal

Las secciones de visibilidad dicen quién puede tocar cada miembro. Lo que va en `private` (el campo FPrice y los métodos SetPrice y GetPriceWithVat) es asunto interno de la clase; lo que va en `public` es su cara visible. El prefijo F para los campos y Get/Set para sus métodos es la convención de Pascal.

Una propiedad parece un campo pero decide qué pasa al leer y al escribir. property Price: Double read FPrice write SetPrice lee el campo directamente y, al escribir, llama al método. Por eso lamp.Price := 34.90 ejecuta en realidad SetPrice(34.90), que solo acepta precios no negativos.

La prueba está en la salida: tras lamp.Price := -5, el precio sigue en 34.90. Nadie fuera de la clase puede saltarse la regla, porque el campo es privado y el único camino para cambiarlo es la propiedad.

PriceWithVat solo tiene read, así que es de solo lectura, y no guarda nada: GetPriceWithVat calcula el precio con el 21 % de IVA cada vez que se consulta. Name, en cambio, es un campo público corriente.

Un detalle de Free Pascal: private protege frente a otras unidades, pero el código de la misma unidad (aquí, el propio programa) aún podría usar FPrice. Si quiere un muro completo, use `strict private`. Así trabajan también los componentes de Lazarus: Caption o Width son propiedades con su setter detrás.

Código · 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.

Salida · fpc main.pas && ./main

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

Para recordar

  • private esconde los detalles; public es lo que se ofrece.
  • read y write pueden ir a un campo o a un método.
  • Un setter valida antes de guardar.
  • Una propiedad sin write es de solo lectura y puede ser calculada.
  • strict private impide el acceso incluso desde la misma unidad.

Ejercicio

Añada una propiedad Stock: Integer con un setter que rechace valores negativos y una propiedad de solo lectura StockValue que devuelva Price * Stock.