Originale-mail to me for new edition

 

Property access

 

Every property has a read specifier, a write specifier, or both. These are called access specifiers and they have the form

read fieldOrMethod

write fieldOrMethod

where fieldOrMethod is the name of a field or method declared in the same class as the property or in an ancestor class.

 

·

If fieldOrMethod is declared in the same class, it must occur before the property declaration. If it is declared in an ancestor class, it must be visible from the descendant; that is, it cannot be a private field or method of an ancestor class declared in a different unit.

·

If fieldOrMethod is a field, it must be of the same type as the property.

·

If fieldOrMethod is a method, it cannot be overloaded. Moreover, access methods for a published property must use the default register calling convention.

·

In a read specifier, if fieldOrMethod is a method, it must be a parameterless function whose result type is the same as the property's type.

·

In a write specifier, if fieldOrMethod is a method, it must be a procedure that takes a single value or const parameter of the same type as the property.

 

For example, given the declaration

property Color: TColor read GetColor write SetColor;

the GetColor method must be declared as

function GetColor: TColor;

and the SetColor method must be declared as one of these:

procedure SetColor(Value: TColor);

procedure SetColor(const Value: TColor);

(The name of SetColor’s parameter, of course, doesn’t have to be Value.)

 

When a property is referenced in an expression, its value is read using the field or method listed in the read specifier. When a property is referenced in an assignment statement, its value is written using the field or method listed in the write specifier.

The example below declares a class called TCompass with a published property called Heading. The value of Heading is read through the FHeading field and written through the SetHeading procedure.

type

  THeading = 0..359;

  TCompass = class(TControl)

  private

    FHeading: THeading;

    procedure SetHeading(Value: THeading);

  published

    property Heading: THeading read FHeading write SetHeading;

    ...

  end;

Given this declaration, the statements

if Compass.Heading = 180 then GoingSouth;

Compass.Heading := 135;

correspond to

if Compass.FHeading = 180 then GoingSouth;

Compass.SetHeading(135);

In the TCompass class, no action is associated with reading the Heading property; the read operation consists of retrieving the value stored in the FHeading field. On the other hand, assigning a value to the Heading property translates into a call to the SetHeading method, which, presumably, stores the new value in the FHeading field as well as performing other actions. For example, SetHeading might be implemented like this:

procedure TCompass.SetHeading(Value: THeading);

begin

  if FHeading <> Value then

  begin

    FHeading := Value;

    Repaint;  // update user interface to reflect new value

  end;

end;

A property whose declaration includes only a read specifier is a read-only property, and one whose declaration includes only a write specifier is a write-only property. It is an error to assign a value to a read-only property or use a write-only property in an expression.

 

Topic groups

 

See also

About class types

Calling conventions

Constant parameters

Fields

Methods: Overview

Overloading methods

Properties: Overview

Published members

 

 

译文

 

属性访问

 

每个属性都有一个read说明符、一个write说明符或者两个都有。它们就是被调用的访问说明符(access specifiers)。访问说明符具有如下形式

read fieldOrMethod

write fieldOrMethod

这里的fieldOrMethod是一个域或方法的名称(不管是域还是方法,都必需是与属性在同一个类或祖先类中声明的)。

 

·

如果fieldOrMethod在同一个类中声明过,那么它必需出现在属性声明之前。如果它声明于祖先类中,那么它必需在后裔类中是可见的;也就是说,如果祖先类的声明在不同的单元中,那么这里的fieldOrMethod不能是一个私有的域或方法。

·

如果fieldOrMethod是一个域,那么它必需与属性具有相同的类型。

·

如果fieldOrMethod是一个方法,那么呀不能被重载。而且,公布属性的访问方法必需使用缺省的register调用约定。

·

read说明符中,如果fieldOrMethod是一个方法,那么它必需是一个无参数的函数并且函数返回的类型与属性的类型相同。

·

write说明符中,如果fieldOrMethod是一个方法,那么它必需是一个过程,并且该过程接受一个单独的值参数或const参数,并且参数类型与属性类型相同。

 

例如,给出如下声明

property Color: TColor read GetColor write SetColor;

这里的GetColor方法必需声明为:

function GetColor: TColor;

SetColor方法必需声明为下列两者之一:

procedure SetColor(Value: TColor);

procedure SetColor(const Value: TColor);

SetColor的参数名称当然不必是Value。)

 

当属性在表达式中被引用时,属性的值通过列于read说明符中的域或方法读出。当属性在赋值语句中被引用时(属性位于赋值符号的左边),属性的值通过列于write说明符中的域或方法被写入。

下面的例子声明了一个叫做TCompass的类,该类公布了一个叫做Heading的属性。Heading的值通过FHeading读取并且通过SetHeading过程被写入。

type

  THeading = 0..359;

  TCompass = class(TControl)

  private

    FHeading: THeading;

    procedure SetHeading(Value: THeading);

  published

    property Heading: THeading read FHeading write SetHeading;

    ...

  end;

给出上面的声明,下列语句

if Compass.Heading = 180 then GoingSouth;

Compass.Heading := 135;

实际上相应为

if Compass.FHeading = 180 then GoingSouth;

Compass.SetHeading(135);

TCompass类中,没有任何动作与Heading属性的读取相关联;read操作的组成只有一部分,即获取存储在FHeading域中的值。另一方面,对Heading属性的赋值解释成为对SetHeading方法的调用,大概推测,该方法会和其他多数方法类似,把新的值存储到FHeading域中。例如,SetHeading方法可能如下实现:

procedure TCompass.SetHeading(Value: THeading);

begin

  if FHeading <> Value then

  begin

    FHeading := Value;

    Repaint;  //更新用户界面以反映新值

  end;

end;

属性声明中只包括read说明符的属性是只读(read-only)属性;属性声明中只包括write说明符的属性是只写(write-only)属性。向只读属性赋值或者读取只写属性的值都将出错。

 

主题组

 

相关主题

关于类类型

调用约定

常量参数

方法:概述

重载方法

属性:概述

公布成员