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.
154
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;
155
|