Originale-mail to me for new edition

 

Property overrides and redeclarations

 

A property declaration that doesn’t specify a type is called a property override. Property overrides allow you to change a property’s inherited visibility or specifiers. The simplest override consists only of the reserved word property followed by an inherited property identifier; this form is used to change a property’s visibility. For example, if an ancestor class declares a property as protected, a derived class can redeclare it in a public or published section of the class. Property overrides can include read, write, stored, default, and nodefault directives; any such directive overrides the corresponding inherited directive. An override can replace an inherited access specifier, add a missing specifier, or increase a property’s visibility, but it cannot remove an access specifier or decrease a property’s visibility. An override can include an implements directive, which adds to the list of implemented interfaces without removing inherited ones.

The following declarations illustrate the use of property overrides.

type

  TAncestor = class

   ...

  protected

    property Size: Integer read FSize;

    property Text: string read GetText write SetText;

    property Color: TColor read FColor write SetColor stored False;

    ...

  end;

type

  TDerived = class(TAncestor)

   ...

  protected

    property Size write SetSize;

  published

    property Text;

    property Color stored True default clBlue;

    ...

  end;

The override of Size adds a write specifier to allow the property to be modified. The overrides of Text and Color change the visibility of the properties from protected to published. The property override of Color also specifies that the property should be filed if its value isn’t clBlue.

 

A redeclaration of a property that includes a type identifier hides the inherited property rather than overriding it. This means that a new property is created with the same name as the inherited one. Any property declaration that specifies a type must be a complete declaration, and must therefore include at least one access specifier.

Whether a property is hidden or overridden in a derived class, property look-up is always static. That is, the declared (compile-time) type of the variable used to identify an object determines the interpretation of its property identifiers. Hence, after the following code executes, reading or assigning a value to MyObject.Value invokes Method1 or Method2, even though MyObject holds an instance of TDescendant. But you can cast MyObject to TDescendant to access the descendant class’s properties and their access specifiers.

type

  TAncestor = class

     ...

    property Value: Integer read Method1 write Method2;

  end;

  TDescendant = class(TAncestor)

     ...

    property Value: Integer read Method3 write Method4;

  end;

var MyObject: TAncestor;

 ...

MyObject := TDescendant.Create;

 

Topic groups

 

See also

Implementing interfaces by delegation

Properties: Overview

Property access

Storage specifiers

Visibility of class members

 

 

译文

 

属性覆盖和再声明

 

不指定属性类型的属性声明叫做属性覆盖(property override)。属性覆盖允许改变属性的继承的可见度或者说明符。最简单的覆盖,只使用保留字property和紧随其后的继承得到的属性标识符;这种形式用于改变属性的可见度。例如,如果一个祖先类声明了一个保护属性,那么派生类可以在公共或公布部分对其进行再声明。属性覆盖可以包括readwritestoreddefaultnodefault等指示字;任何这样的指示字都覆盖相应继承得到的指示字。属性覆盖可以替换继承的访问说明符,增加丢失的说明符,或者提高属性的可见度,但却不能删除访问说明符或降低属性的可见度。属性覆盖可以包括implements指示字,这样只是增加属性到实现的接口列表而没有删除继承得到的属性。

下面的声明举例说明了属性覆盖的使用。

type

  TAncestor = class

   ...

  protected

    property Size: Integer read FSize;

    property Text: string read GetText write SetText;

    property Color: TColor read FColor write SetColor stored False;

    ...

  end;

type

  TDerived = class(TAncestor)

   ...

  protected

    property Size write SetSize;

  published

    property Text;

    property Color stored True default clBlue;

    ...

  end;

Size的覆盖增加了write说明符以允许属性被修改。TextColor的覆盖改变了属性的可见度:从保护属性提高为公布属性。此外,Color的属性覆盖还增加了default说明符,使该域在值不是clBlue时保存到文件。

 

包括了类型标识符的属性再声明将隐藏继承得到的属性,这优于属性覆盖。也就是说,创建了一个与继承的属性同名的新的属性。任何指定了类型的属性声明必需是一个完整的声明,并且因此必需至少包括一个访问说明符。

不管属性在派生类中是被隐藏还是被覆盖,属性查找总是静态的。也就是说,用于标识对象的变量,其声明时(编译时)的类型决定了其属性标识符的解释。因此,下列代码执行后,对MyObject.Value的读或写将调用Method1Method2,尽管MyObject保存的是TDescendant实例。不过,可以将MyObject强制转换为TDescendant类型,以访问后裔类的属性及相应的访问说明符。

type

  TAncestor = class

     ...

    property Value: Integer read Method1 write Method2;

  end;

  TDescendant = class(TAncestor)

     ...

    property Value: Integer read Method3 write Method4;

  end;

var MyObject: TAncestor;

 ...

MyObject := TDescendant.Create;

 

主题组

 

相关主题

通过委托实现接口

属性:概述

属性访问

存储说明符

类成员的可见度