属性(Property)

本节学习属性(Property) 定义、语法、规范、序列化

Property 是什么

property 是 Pascal 语法糖,对外表现如同字段,底层实际调用getter读取/setter写入,用来封装私有字段、统一读写逻辑、附加副作用。

  1. 读写可控属性:赋值/取值时自动执行额外逻辑(界面重绘、同步组件、校验数值);
  2. 只读属性:外部仅可读、不可直接赋值,内部通过专属方法修改数据。
program Demo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
  SysUtils;

type
  TWebPage = class
  private
    FURL: string;
    FColorRGB: Integer;
    procedure SetColorRGB(const Value: Integer);
  public
    property URL: string read FURL;
    property ColorRGB: Integer read FColorRGB write SetColorRGB;

    procedure Load(const AnURL: string);
    procedure PrintStatus;
  end;

procedure TWebPage.Load(const AnURL: string);
begin
  FURL := AnURL;
  Writeln('Load page: ', AnURL);
end;

procedure TWebPage.SetColorRGB(const Value: Integer);
begin
  if FColorRGB <> Value then
  begin
    FColorRGB := Value;
    Writeln('Color updated, value = ', Value);
    Writeln('Sync component color to ', Value);
  end;
end;

procedure TWebPage.PrintStatus;
begin
  Writeln('==== Page Info ====');
  Writeln('URL(read-only): ', URL);
  Writeln('ColorRGB(rw): ', ColorRGB);
  Writeln('==================');
  Writeln;
end;

var
  Page: TWebPage;
begin
  Page := TWebPage.Create;
  try
    Page.Load('https://www.foxdevelop.com/');
    Page.ColorRGB := 255;
    Page.PrintStatus;

    Page.ColorRGB := 255;
    Page.PrintStatus;

    Page.ColorRGB := 65535;
    Page.PrintStatus;

    // Page.URL := 'test'; // Compile error, URL is read-only
  finally
    Page.Free;
  end;
  Readln;
end.Code language: Delphi (delphi)

TWebPage中 URL属性只能读,如果要写入(修改),要靠Load这个过程。

FColorRGB这个属性可以读取,但是写入(修改)要靠SetColorRGB这个过程。

另外还有一个PrintStatus属性,就是一个普通的过程,用来输出TWebPage的内部信息。

运行结果

Load page: https://www.foxdevelop.com/
Color updated, value = 255
Sync component color to 255
==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 255
==================

==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 255
==================

Color updated, value = 65535
Sync component color to 65535
==== Page Info ====
URL(read-only): https://www.foxdevelop.com/
ColorRGB(rw): 65535
==================Code language: JavaScript (javascript)

2. property 三要素声明规则

声明属性必须指定读取方式,可选指定写入方式

read 读取源:二选一

  • 直接绑定私有字段(速度最快,无额外函数开销)
  • 无参getter函数,返回值与属性类型完全匹配

write 写入源(可选,不写则为只读):二选一

  • 直接绑定私有字段
  • 单参数setter函数,参数类型与属性完全匹配

附加修饰(序列化专用):defaultstored

编译器强制校验类型匹配:

  • Integer 属性:getter必须无参返回Integer / read绑定Integer私有字段
  • String 属性:setter必须接收const string参数

Published 属性与序列化

1. 什么是序列化

将对象完整数据写入流(文件/内存/JSON),后续可从流还原对象;

Lazarus窗体.lfm、Delphi.dfm窗体文件底层完全依赖该机制。

  • 核心前提:属性必须放在 published 段,RTTI运行时类型信息才能识别
  • 配套工具单元:
  • LResources:读写窗体lfm文件
  • FpJsonRtti / CastleComponentSerialize:对象序列化JSON

2. 序列化专用修饰符

default <常量>:标记属性默认值

  • 仅给序列化工具做判断:若对象构造完成后属性=default值,序列化时省略存储,减小文件体积
  • 不会自动初始化:构造函数必须手动给字段赋值为default对应数值

stored <布尔/方法>:控制是否序列化保存该属性

  • stored True:默认,序列化写入文件
  • stored False:永远不保存该属性
  • stored IsNeedSave:调用布尔方法动态判断是否存储

序列化示例

type
  TWebPage = class
  private
    FColor: TColor;
    function SetColor(const Value: TColor): TColor;
  published
    // default clBlack 代表默认黑色,构造函数必须手动 FColor := clBlack
    property Color: TColor read FColor write SetColor default clBlack;
    // stored False 不会保存到lfm/json
    property TempCache: string read FTemp write FTemp stored False;
  end;Code language: Delphi (delphi)

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注