Области видимости
При описании нового класса важен разумный компромисс. С одной стороны, требуется скрыть от других методы и поля, представляющие собой внутреннее устройство класса (для этого и придуманы свойства). Маловажные детали на уровне пользователя объекта будут бесполезны и только помешают целостности восприятия.
С другой стороны, если слишком ограничить того, кто будет порождать классы-потомки, и не обеспечить ему достаточный набор инструментальных средств и свободу маневра, то он и не станет использовать ваш класс.
В модели объектов языка Object Pascal существует механизм доступа к составным частям объекта, определяющий области, где ими можно пользоваться (области видимости). Поля и методы могут относиться к четырем группам (секциям), отличающимся областями видимости. Методы и свойства могут быть общими (секция public), личными (секция private), защищенными (секция protected) и опубликованными (секция published). Есть еще и пятая группа, automated, она ранее использовалась для создания объектов СОМ; теперь она присутствует в языке только для обратной совместимости с программами на Delphi версий 3-5.
Области видимости, определяемые первыми тремя директивами, таковы.
- Поля, свойства и методы секции public не имеют ограничений на видимость. Они доступны из других функций и методов объектов как в данном модуле, так и во всех прочих, ссылающихся на него.
- Поля, свойства и методы, находящиеся в секции private, доступны только в методах класса и в функциях, содержащихся в том же модуле, что и описываемый класс. Такая директива позволяет полностью скрыть детали внутренней реализации класса. Свойства и методы из секции private можно изменять, и это не будет сказываться на программах, работающих с объектами этого класса. Единственный способ для кого-то другого обратиться к ним – переписать заново созданный вами модуль (если, конечно, доступны исходные тексты).
- Поля, свойства и методы секции protected также доступны только внутри модуля с описываемым классом. Но – и это главное – они доступны в классах, являющихся потомками данного класса, в том числе и в других модулях. Такие элементы особенно необходимы для разработчиков новых компонентов – потомков уже существующих. Оставляя свободу модернизации класса, они все же скрывают детали реализации от того, кто только пользуется объектами этого класса.
Рассмотрим пример, иллюстрирующий три варианта областей видимости.
Листинг 1.1. Пример задания областей видимости методов.
unit First; | unit Second; interface | interface | uses First; type | type TFirstObj = class | TSecondObj =class(TFirstObj} private | procedure Method4; procedure Method1; | 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; | Method1; {недопустимо – произойдет ошибка компиляции} AFirstObj.Method1;(допустимо)| AFirstObj.Method2; {допустимо}| Method2; {допустимо} AFirstObj.MethodS; {допустимо}| Method3, – {допустимо} AFirstObj.Free; | end; end; | procedure TestProc2; procedure TFirstObj.Method1; | begin begin |AFirstObj: = TFirstObj.Create; ShowMessage('1'); |AFirstObj.Method1;{недопустимо} end; |AFirstObj.Method2;{недопустимо} procedure TFirstObj.Method2; |AFirstObj.Method3;{допустимо} begin |AFirstObj.Free; ShowMessage('2'); Methodl; |ASecondCbj: = TSecondObj.Create; end; |ASecondObj.Method1;{недопустимо} procedureTFirstObj.Method3; |ASecondObj.Method2;{допустимо} begin |ASecondObj.Method3;{допустимо} ShowMessage('3'); |ASecondObj.Free; Method2; | end; end; |end. end. |