На этом шаге мы рассмотрим способы переопределения свойств.
На 134 шаге было приведено описание простейших свойств, состоящих из идентификатора свойства и спецификаторов доступа read и write, которые обращаются непосредственно к контролируемому свойством полю. Но если посмотреть на синтаксис объявления свойств, то можно заметить, что в минимальном варианте допускается указывать даже только один идентификатор свойства. Такое действительно возможно, но только не для впервые описываемых свойств, а в случае, когда наследуется класс, в котором свойство с таким идентификатором было уже определено.
Объявление свойства, которое имеет такой же идентификатор, как и у свойства одного из родительских классов называется переопределением свойства (property override). При переопределении свойства его интерфейс и спецификаторы могут не указываться.
Переопределение свойства при объявлении класса-потомка предоставляет программисту следующие возможности:
Правда, что касается спецификаторов доступа, то следует заметить, что переопределение свойства может или изменять наследуемый спецификатор, или добавлять отсутствующий спецификатор, но не может полностью отменить действие уже описанного в родительском классе спецификатора доступа.
Самый элементарный вид переопределения, когда указан один идентификатор свойства, объявленного в классе-предке, может быть использован только для изменения области видимости родительского свойства при сохранении действия всех его спецификаторов. Если же при переопределении описаны какие-либо спецификаторы доступа или сохранения, то они отменяют действия одноименных наследуемых спецификаторов и определяют свои собственные действия. Механизм переопределения свойств в этом смысле похож на механизм отмены действия глобальных переменных, если в процедуре объявляются одноименные локальные переменные.
Приведем пример, демонстрирующий различные виды переопределения свойств.
type TMyProperties = class private FField1 : Integer; { Поле первого свойства } FField2 : Integer; { Поле второго свойства } property Property1 : Integer { Первое свойство } read FField1 write FField1; protected FField3 : Integer; { Поле третьего свойства } property Property2 : Integer { Второе свойство } read FField2 stored True default 100; property Property3 : Integer { Третье свойство } write FField3; end; TOvverideProperty1 = class (TMyProperties) published property Property1; { Переопределяется только область видимости свойства } { Property1 с private на published при сохранении } { действия спецификаторов read и write. } TOvverideProperty2 = class (TMyProperties) protected function GetProperty2 : Integer; procedure SetProperty2 (Value : Integer); public property Property2 read GetProperty2 write SetProperty2 stored False; { Переопределяется область видимости свойства Property2 } { c protected на public, изменяется действие спецификаторов } { read и stored, а также добавляется спецификатор write. } end; TOvverideProperty3 = class (TMyProperties) protected property Property3 read FField3; { Область видимости свойства Property3 не переопределяется, } { а только добавляется спецификатор чтения read. } end;
На следующем шаге мы рассмотрим свойства-массивы.