Области видимости

При описании нового класса важен разумный компромисс. С одной стороны, требуется скрыть от других методы и поля, представляющие собой внутреннее устройство класса (для этого и придуманы свойства). Маловажные детали на уровне пользователя объекта будут бесполезны и только помешают целостности восприятия.

С другой стороны, если слишком ограничить того, кто будет порождать классы-потомки, и не обеспечить ему достаточный набор инструментальных средств и свободу маневра, то он и не станет использовать ваш класс.

В модели объектов языка Object Pascal существует механизм доступа к составным частям объекта, определяющий области, где ими можно пользоваться (области видимости). Поля и методы могут относиться к четырем группам (секциям), отличающимся областями видимости. Методы и свойства могут быть общими (секция public), личными (секция private), защищенными (секция protected) и опубликованными (секция published). Есть еще и пятая группа, automated, она ранее использовалась для создания объектов СОМ; теперь она присутствует в языке только для обратной совместимости с программами на Delphi версий 3—5.

Области видимости, определяемые первыми тремя директивами, таковы.

Рассмотрим пример, иллюстрирующий три варианта областей видимости.

Листинг 1.1. Пример задания областей видимости методов

unit First;             |  unit Second; 

interface               |  interface

                        |   uses First;                                  

type                    |   type

TFirstObj = class       |  TSecondObj =class(TFirstObj}

private                 |  procedure Method4;

procedure Methodl;      |  end;

protected               |

procedure Method2;      |

public                  |

procedure Methods;      |

end;                    |

procedure TestProcl;    |  procedure TestProc2;

implementation          |  implementation

uses dialogs;           |  varAFirstObj :TFirstObj;

var AFirstObj: TFirstObj;|ASecondObj: TSecondObj;

procedure TestProcl;    |  procedure TSecondObj.Method4;

begin                   |  begin

AFirstCbj := TFirstObj.Create; | Methodl; {недопустимо -

AFirstObj.Methodl;(допустимо)|

                          |произойдет ошибка компиляции}

AFirstObj.Method2; {допустимо}| Method2; {допустимо}

AFirstObj.MethodS; {допустимо}| Methods,- {допустимо}

AFirstObj.Free;               | end;

end;

                              | procedure TestProc2;

procedure TFirstObj.Methodl;  | begin

begin                  |AFirstObj:=TFirstObj.Create;

ShowMessage('1');      |AFirstObj.Methodl;{недопустимо}

end;                   |AFirstObj.Method2;{недопустимо}

procedure TFirstObj.Method2;       

                      |AFirstObj.Method3;{допустимо}

begin                 |AFirstObj.Free;

ShowMessage('2');

Methodl;              |ASecondCbj:= TSecondObj.Create;

end;                  |ASecondObj.Methodl;{недопустимо}

procedureTFirstObj.Method3;

|ASecondObj.Method2;{допустимо}

begin                   |ASecondObj.MethodS;{допустимо}

ShowMessage('3');       |ASecondObj.Free;

Method2;                | end;

end;                                        |end.

end.                    | 

Если к этому примеру добавить модуль Third и попробовать вызвать методы классов TFirstObj и TSecondObj оттуда, то к числу недоступных будет отнесен и Method2 — он доступен только в том модуле, в котором описан.

Наконец, область видимости, определяемая четвертой директивой — published, имеет особое значение для интерфейса визуального проектирования Delphi. В этой секции должны быть собраны те свойства объекта, которые будут видны не только во время исполнения приложения, но и из среды разработки. Публиковать можно свойства большинства типов, за исключением старого типа real (теперь он называется rеаl48), свойств типа "массив" и некоторых других. Все свойства компонентов, доступные через

Инспектор объектов, являются их опубликованными свойствами. Во время выполнения такие свойства общедоступны, как и public.

Три области видимости — private, protected, public — как бы упорядочены по возрастанию видимости методов. В классах-потомках можно повысить видимость методов и свойств, но не понизить ее. При описании дочернего класса можно переносить методы и свойства из одной сферы видимости в другую, не переписывая их заново и даже не описывая — достаточно упомянуть о нем в другом месте:

type

TFirstObj = class 

private

FNumber: Integer; 

protected

property Number: Integer read: FNumber;

 end;

...

TSecondObj = class(TFirstObj) 

published

property Number; 

end;

Если какое-либо свойство объекта из состава VCL принадлежит к области public, вернуть его в private невозможно. Напротив, обратная процедура широко практикуется в Delphi. У многих компонентов (например, TEdit) есть предок (в данном случае TCustomEdit), который отличается только отсутствием опубликованных свойств. Так что, если вы хотите создать новый редактирующий компонент, порождайте его на базе TCustomEdit и публикуйте только те свойства, которые считаете нужными. Разумеется, если вы поместили свойство в область private, "достать" его оттуда в потомках возможности уже нет.