首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 介面編程 (4):介面屬性——唯讀寫方法,無字段

     編輯:Delphi

介面屬性的特殊規則

Delphi 介面中只能聲明方法與屬性,不能聲明字段。因此介面屬性的 read/write 必須映射到方法,而非字段。實現類負責提供存儲字段與讀寫方法,屬性語義歸屬於介面契約。

完整代碼示範

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  // 1. 介面聲明屬性 Name,讀寫映射到方法
  INameable = interface
    ['{B2C3D4E5-F6A7-8901-BCDE-F23456789012}']
    function GetName: string;
    procedure SetName(const Value: string);
    property Name: string read GetName write SetName;
  end;

  // 2. 實現類提供字段存儲與方法實現
  TNamedObject = class(TInterfacedObject, INameable)
  private
    FName: string; // 實際存儲字段,介面不可見
  public
    function GetName: string;
    procedure SetName(const Value: string);
  end;

  TForm1 = class(TForm)
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TNamedObject }
function TNamedObject.GetName: string;
begin
  Result := FName;
end;

procedure TNamedObject.SetName(const Value: string);
begin
  FName := Value;
end;

{ TForm1 }
procedure TForm1.btnTestClick(Sender: TObject);
var
  Obj: TNamedObject;
  Intf: INameable;
begin
  Obj := TNamedObject.Create;
  Intf := Obj; // 隱式轉換,RefCount=1

  // 僅通過介面訪問屬性
  Intf.Name := 'ABC';
  ShowMessage('介面讀取: ' + Intf.Name); // ABC

  // 編譯錯誤:Obj.Name 不存在(屬性屬於介面,不屬於類)
  // ShowMessage(Obj.Name);

  // 驗證類內部字段確實被修改
  ShowMessage('類字段直接讀: ' + Obj.FName); // ABC (若 FName 為 public/protected)

  // Intf 離開作用域自動釋放 Obj
end;

end.

核心規則總結

規則說明
介面無字段不能在介面中聲明 FName: string;
屬性讀寫必須是方法read GetName write SetName,不能 read FName
方法可在介面聲明也可只在類實現介面聲明則成契約一部分;類私有實現則屬實現細節
屬性歸屬介面類實例無該屬性,只能通過介面引用訪問
實現類自行管理存儲字段、屬性包裝、計算屬性、委託其他對象皆可

進階模式:計算屬性與委託

type
  IReadOnlyInfo = interface
    function GetFullName: string;
    function GetAge: Integer;
    property FullName: string read GetFullName; // 唯讀計算屬性
    property Age: Integer read GetAge;
  end;

  TPerson = class(TInterfacedObject, IReadOnlyInfo)
  private
    FFirstName, FLastName: string;
    FBirthDate: TDate;
  public
    function GetFullName: string;
    function GetAge: Integer;
  end;

function TPerson.GetFullName: string;
begin
  Result := FFirstName + ' ' + FLastName; // 計算屬性,無存儲字段
end;

function TPerson.GetAge: Integer;
begin
  Result := YearsBetween(Date, FBirthDate); // 委託計算
end;

介面屬性 vs 類屬性對比

維度類屬性介面屬性
存儲可直接映射字段必須映射方法
可見性public/protected/private/published隱式 public(介面無訪問控制)
RTTI完整支援 (published)僅方法有 RTTI,屬性本身無
繼承單繼承,可覆寫介面可繼承介面,類實現多介面
用途對象狀態封裝、IDE 設計時屬性契約定義、多態訪問、跨模塊邊界

常見誤區

  1. 以為類有介面屬性:Obj.Name 編譯失敗,必須 (Obj as INameable).Name 或 Intf.Name。
  2. 介面屬性 write 映射到字段:非法,必須是 procedure SetX。
  3. 介面屬性可以是數組屬性:支援 property Items[Index: Integer]: string read GetItem write SetItem;,但索引類型受限。

總結

Delphi 介面屬性是純行為契約:無字段、唯方法、歸介面、實現類自管存儲。這種設計強制關注點分離——介面定義「能做什麼」,類決定「怎麼存、怎麼算」。掌握此規則,即可設計出高內聚、低耦合、易測試、易替換的介面契約體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved