Indexed properties索引型的属性
你可以将许多不同的属性映射到一个相同的读或写的方法,只需为每个属性指定一个索引值。这个索引值将被传递给读或写的方法以区别不同属性。
你甚至可以将数组型和索引型混合使用。读者和写者的方法将会区分他们——将数组的索引作为第一个参数,接着才是索引值。
Default values默认值
属性还用到stored和default两个指示符。这里的信息与 Delphi的Object Pascal语言的特性关系不大,但是Delphi的IDE将其用作保存Form的描述。stored指示符的值可以是一个Boolean类型的常量,也可以是一个Boolean型的字段,或是一个不需任何参数直接返回Boolean值方法。default指示符的值应当是与该属性的类型相同的一个常量。只有枚举型,整形以及集合类型的属性可以有一个缺省(default)的值。stored和default指示符只对发布的属性才有意义。
为了将缺省的数组数型与缺省的值区别开来,缺省数组的指示符以一个分号跟在属性的声明后面。缺省值指示符则直接置于属性声明以后。参见第五章了解有关default指示符的内容。
Using properties使用属性
通常情况下定义一个类时,我们将所有的字段设置为私有的,然后声明许多公开的属性来访问他们。然而Delphi并未对属性直接访问字段方式表示不满。但是使用属性,你可以在未来的某个时刻改变属性的实现,比如在字段值发生改变是增加校验等。你也可以使用属性来强制访问级别,比如当一个字段的之不能被改变时使用一个只读的属性。例 2-11显示的是声明和使用属性的几种方式。
例 2-11:声明和使用属性 type TCustomer = record Name: string; TaxIDNumber: string[9]; end; TAccount = class private fCustomer: TCustomer; fBalance: Currency; fNumber: Cardinal; procedure SetBalance(NewBalance: Currency); published property Balance: Currency read fBalance write SetBalance; property Number: Cardinal read fNumber; //不可改变 property CustName: string read fCustomer.Name; end; TSavingsAccount = class(TAccount) private fInterestRate: Integer; published property InterestRate: Integer read fInterestRate write fInterestRate default DefaultInterestRate; end; TLinkedAccount = class(TObject) private fAccounts: array[0..1] of TAccount; function GetAccount(Index: Integer): TAccount; public //两种属性访问数组的方法:使用索引或者引用一个数组元素 property Checking: TAccount index 0 read GetAccount; property Savings: TAccount read fAccounts[1]; end; TAccountList = class private fList: TList; function GetAccount(Index: Integer): TAccount; procedure SetAccount(Index: Integer; Account: TAccount); function GetCount: Integer; protected property List: TList read fList; public property Count: Integer read GetCount; property Accounts[Index: Integer]: TAccount read GetAccount write SetAccount; default; end; procedure TAccount.SetBalance(NewBalance: Currency); begin if NewBalance < 0 then raise EOverdrawnException.Create; fBalance := NewBalance; end; function TLinkedAccount.GetAccount(Index: Integer): TAccount; begin Result := fAccounts[Index] end; function TAccountList.GetCount: Integer; begin Result := List.Count end; function TAccountList.GetAccount(Index: Integer): TAccount; begin Result := List[Index] end; procedure TAccountList.SetAccount(Index: Integer; Account: TAccount); begin fList[Index] := Account end; |